def test_announcements(self): email = '*****@*****.**' actions.login(email, is_admin=True) self._add_announcement({ 'title': 'My Test Title', 'date': '2015/02/03', 'is_draft': False, 'send_email': False, 'html': 'Four score and seven years ago, our founding fathers' }) self._add_announcement({ 'title': 'My Test Title', 'date': '2015/02/03', 'is_draft': True, 'send_email': False, 'html': 'Standing beneath this serene sky, overlooking these', }) response = self.get('dashboard?action=settings_search') index_token = self.get_xsrf_token(response.body, 'gcb-index-course') response = self.post('dashboard?action=index_course', {'xsrf_token': index_token}) self.execute_all_deferred_tasks() # This matches an announcement in the Power Searching course response = self.get( 'search?query=Four%20score%20seven%20years') self.assertIn('gcb-search-result', response.body) self.assertIn('announcements#', response.body) # The draft announcement in Power Searching should not be indexed response = self.get('search?query=Standing%20beneath%20serene') self.assertNotIn('gcb-search-result', response.body) self.assertNotIn('announcements#', response.body)
def test_certificate_table_entry(self): actions.login('*****@*****.**') models.Student.add_new_student_for_current_user('Test User', None, self) student = models.Student.get_by_email('*****@*****.**') all_courses = sites.get_all_courses() app_context = all_courses[0] course = courses.Course(None, app_context=app_context) # If the student is qualified, a link is shown self.is_qualified = True mock_handler = MockHandler() table_entry = certificate.get_certificate_table_entry( mock_handler, student, course) self.assertEquals('Certificate', table_entry[0]) link = str(table_entry[1]) self.assertEquals( '<a href="certificate">Click for certificate</a> ' '| <a href="certificate.pdf">Download PDF</a>', link) # If the student is not qualified, a message is shown self.is_qualified = False table_entry = certificate.get_certificate_table_entry( mock_handler, student, course) self.assertEquals('Certificate', table_entry[0]) self.assertIn( 'You have not yet met the course requirements', table_entry[1])
def test_not_enough_assignments_to_allocate(self): """Test for the case when there are too few assignments in the pool.""" email = '*****@*****.**' name = 'Student 1' submission = transforms.dumps([ {'index': 0, 'type': 'regex', 'value': 'S1-1', 'correct': True}, {'index': 1, 'type': 'choices', 'value': 3, 'correct': False}, {'index': 2, 'type': 'regex', 'value': 'is-S1', 'correct': True}, ]) payload = { 'answers': submission, 'assessment_type': LEGACY_REVIEW_UNIT_ID} actions.login(email) actions.register(self, name) response = actions.submit_assessment( self, LEGACY_REVIEW_UNIT_ID, payload) # The student goes to the review dashboard and requests an assignment # to review -- but there is nothing to review. response = actions.request_new_review( self, LEGACY_REVIEW_UNIT_ID, expected_status_code=200) assert_does_not_contain('Assignment to review', response.body) assert_contains('Sorry, there are no new submissions ', response.body) assert_contains('disabled="true"', response.body) actions.logout()
def setUp(self): super(CertificateCriteriaTestCase, self).setUp() self.base = '/' + self.COURSE_NAME context = actions.simple_add_course( self.COURSE_NAME, self.ADMIN_EMAIL, 'Certificate Criteria') self.old_namespace = namespace_manager.get_namespace() namespace_manager.set_namespace('ns_%s' % self.COURSE_NAME) self.course = courses.Course(None, context) self.course.save() actions.login(self.STUDENT_EMAIL) actions.register(self, self.STUDENT_EMAIL) self.student = ( models.StudentProfileDAO.get_enrolled_student_by_email_for( self.STUDENT_EMAIL, context)) # Override course.yaml settings by patching app_context. self.get_environ_old = sites.ApplicationContext.get_environ self.certificate_criteria = [] def get_environ_new(app_context): environ = self.get_environ_old(app_context) environ['certificate_criteria'] = self.certificate_criteria return environ sites.ApplicationContext.get_environ = get_environ_new
def test_index_search_clear(self): email = '*****@*****.**' actions.login(email, is_admin=True) response = self.get('dashboard?action=search') index_token = self.get_xsrf_token(response.body, 'gcb-index-course') clear_token = self.get_xsrf_token(response.body, 'gcb-clear-index') response = self.post('dashboard?action=index_course', {'xsrf_token': index_token}) self.execute_all_deferred_tasks() # weather is a term found in the Power Searching Course and should not # be in the HTML returned by the patched urlfetch in SearchTestBase response = self.get('search?query=weather') self.assertNotIn('gcb-search-result', response.body) # This term should be present as it is in the dummy content. response = self.get('search?query=cogito%20ergo%20sum') self.assertIn('gcb-search-result', response.body) response = self.post('dashboard?action=clear_index', {'xsrf_token': clear_token}) self.execute_all_deferred_tasks() # After the index is cleared, it shouldn't match anything response = self.get('search?query=cogito%20ergo%20sum') self.assertNotIn('gcb-search-result', response.body)
def test_multiple_course(self): """Tests when multiple courses are available.""" sites.setup_courses('course:/test::ns_test, course:/:/') name = 'Test completed course' email = 'Student' # Make the course available. get_environ_old = sites.ApplicationContext.get_environ def get_environ_new(self): environ = get_environ_old(self) environ['course']['now_available'] = True return environ sites.ApplicationContext.get_environ = get_environ_new actions.login(email) actions.register(self, name) response = self.get('/explorer/courses') # Assert if 'View course list' text is shown on my course page. assert_contains('View course list', response.body) # Clean up app_context. sites.ApplicationContext.get_environ = get_environ_old sites.reset_courses()
def setUp(self): super(DashboardAccessTestCase, self).setUp() actions.login(self.ADMIN_EMAIL, is_admin=True) context = actions.simple_add_course( self.ACCESS_COURSE_NAME, self.ADMIN_EMAIL, 'Course with access') self.course_with_access = courses.Course(None, context) with Namespace(self.course_with_access.app_context.namespace): role_dto = models.RoleDTO(None, { 'name': self.ROLE, 'users': [self.USER_EMAIL], 'permissions': {dashboard.custom_module.name: [self.PERMISSION]} }) models.RoleDAO.save(role_dto) context = actions.simple_add_course( self.NO_ACCESS_COURSE_NAME, self.ADMIN_EMAIL, 'Course with no access' ) self.course_without_access = courses.Course(None, context) # pylint: disable=W0212 self.old_nav_mappings = DashboardHandler._custom_nav_mappings # pylint: disable=W0212 DashboardHandler._custom_nav_mappings = {self.ACTION: 'outline'} DashboardHandler.map_action_to_permission( 'get_%s' % self.ACTION, self.PERMISSION) actions.logout()
def test_certificate_table_entry(self): actions.login('*****@*****.**') models.Student.add_new_student_for_current_user( 'Test User', None, self) student = models.Student.get_by_email('*****@*****.**') all_courses = sites.get_all_courses() app_context = all_courses[0] course = courses.Course(None, app_context=app_context) # If the student is qualified, a link is shown self.is_qualified = True mock_handler = MockHandler() table_entry = certificate.get_certificate_table_entry( mock_handler, student, course) self.assertEquals('Certificate', table_entry[0]) link = str(table_entry[1]) self.assertEquals( '<a href="certificate">Click for certificate</a> ' '| <a href="certificate.pdf">Download PDF</a>', link) # If the student is not qualified, a message is shown self.is_qualified = False table_entry = certificate.get_certificate_table_entry( mock_handler, student, course) self.assertEquals('Certificate', table_entry[0]) self.assertIn('You have not yet met the course requirements', table_entry[1])
def test_certificate_should_have_student_nickname(self): actions.login('*****@*****.**') models.Student.add_new_student_for_current_user('Jane Doe', None, self) response = self.get('/certificate') self.assertEquals(200, response.status_code) self.assertIn('Jane Doe', response.body)
def setUp(self): super(PeerReviewDashboardStudentTest, self).setUp() self.base = '/' + self.COURSE_NAME context = actions.simple_add_course( self.COURSE_NAME, '*****@*****.**', 'Peer Back Button Child') self.course = courses.Course(None, context) self.assessment = self.course.add_assessment() self.assessment.title = 'Assessment' self.assessment.html_content = 'assessment content' self.assessment.workflow_yaml = ( '{grader: human,' 'matcher: peer,' 'review_due_date: \'2034-07-01 12:00\',' 'review_min_count: 1,' 'review_window_mins: 20,' 'submission_due_date: \'2034-07-01 12:00\'}') self.assessment.now_available = True self.course.save() actions.login(self.STUDENT_EMAIL) actions.register(self, self.STUDENT_EMAIL) actions.submit_assessment( self, self.assessment.unit_id, {'answers': '', 'score': 0, 'assessment_type': self.assessment.unit_id}, presubmit_checks=False )
def test_single_completed_course(self): """Tests when a single completed course is present.""" user = self.make_test_user('*****@*****.**') name = 'Test Assessments' # Register. actions.login(user.email()) actions.register(self, name) response = self.get('/explorer') # Before a course is not completed, # explorer page should not show 'view score' button. assert_does_not_contain('View score', response.body) # Assign a grade to the course enrolled to mark it complete. profile = PersonalProfile.get_by_key_name(user.user_id()) info = {'final_grade': 'A'} course_info_dict = {'': info} profile.course_info = transforms.dumps(course_info_dict) profile.put() # Check if 'View score' text is visible on profile page. response = self.get('/explorer/profile') assert_contains('View score', response.body) # Check if 'Go to course' button is not visible on explorer page. response = self.get('/explorer') assert_does_not_contain('Go to course', response.body) # Check if 'View score' button is visible on explorer page. response = self.get('/explorer') assert_contains('View score', response.body)
def test_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&tab=students') assert_contains( 'Google > Dashboard > Analytics > Students', response.body) assert_contains('have not been calculated yet', response.body) response = response.forms[ 'gcb-generate-analytics-data'].submit().follow() assert len(self.taskq.GetTasks('default')) == ( ProgressAnalyticsTest.EXPECTED_TASK_COUNT) assert_contains('is running', response.body) self.execute_all_deferred_tasks() response = self.get(response.request.url) 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', response.body) assert_contains( 'No student progress has been recorded for this course.', response.body) actions.logout()
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_cancel_map_reduce(self): email = '*****@*****.**' actions.login(email, is_admin=True) response = self.get('dashboard?action=analytics&tab=peer_review') response = response.forms[ 'gcb-run-visualization-peer_review'].submit().follow() # Launch 1st stage of map/reduce job; we must do this in order to # get the pipeline woken up enough to have built a root pipeline # record. Without this, we do not have an ID to use when canceling. self.execute_all_deferred_tasks(iteration_limit=1) # Cancel the job. response = response.forms[ 'gcb-cancel-visualization-peer_review'].submit().follow() assert_contains('Canceled by ' + email, response.body) # Now permit any pending tasks to complete, and expect the job's # status message to remain at "Canceled by ...". # # If the cancel didn't take effect, the map/reduce should have run to # completion and the job's status would change to completed, changing # the message. This is verified in # model_jobs.JobOperationsTest.test_killed_job_can_still_complete self.execute_all_deferred_tasks() response = self.get(response.request.url) assert_contains('Canceled by ' + email, 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()
def test_not_enough_assignments_to_allocate(self): """Test for the case when there are too few assignments in the pool.""" email = "*****@*****.**" name = "Student 1" submission = transforms.dumps( [ {"index": 0, "type": "regex", "value": "S1-1", "correct": True}, {"index": 1, "type": "choices", "value": 3, "correct": False}, {"index": 2, "type": "regex", "value": "is-S1", "correct": True}, ] ) payload = {"answers": submission, "assessment_type": LEGACY_REVIEW_UNIT_ID} actions.login(email) actions.register(self, name) response = actions.submit_assessment(self, LEGACY_REVIEW_UNIT_ID, payload) # The student goes to the review dashboard and requests an assignment # to review -- but there is nothing to review. response = actions.request_new_review(self, LEGACY_REVIEW_UNIT_ID, expected_status_code=200) assert_does_not_contain("Assignment to review", response.body) assert_contains("Sorry, there are no new submissions ", response.body) assert_contains('disabled="true"', response.body) actions.logout()
def test_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_students') assert_contains('Google > Dashboard > Manage > Students', response.body) assert_contains('have not been calculated yet', response.body) response = response.forms['gcb-generate-analytics-data'].submit( ).follow() assert len(self.taskq.GetTasks('default')) == ( ProgressAnalyticsTest.EXPECTED_TASK_COUNT) assert_contains('is running', response.body) self.execute_all_deferred_tasks() response = self.get(response.request.url) 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', response.body) assert_contains( 'No student progress has been recorded for this course.', response.body) actions.logout()
def test_registration_closed(self): """Test student registration when course is full.""" email = '*****@*****.**' name = 'Test Registration Closed' # Override course.yaml settings by patching app_context. get_environ_old = sites.ApplicationContext.get_environ def get_environ_new(self): environ = get_environ_old(self) environ['reg_form']['can_register'] = False return environ sites.ApplicationContext.get_environ = get_environ_new # Try to login and register. actions.login(email) try: actions.register(self, name) raise actions.ShouldHaveFailedByNow( 'Expected to fail: new registrations should not be allowed ' 'when registration is closed.') except actions.ShouldHaveFailedByNow as e: raise e except: pass # Clean up app_context. sites.ApplicationContext.get_environ = get_environ_old
def setUp(self): super(DashboardAccessTestCase, self).setUp() actions.login(self.ADMIN_EMAIL, is_admin=True) context = actions.simple_add_course( self.ACCESS_COURSE_NAME, self.ADMIN_EMAIL, 'Course with access') self.course_with_access = courses.Course(None, context) with Namespace(self.course_with_access.app_context.namespace): role_dto = models.RoleDTO(None, { 'name': self.ROLE, 'users': [self.USER_EMAIL], 'permissions': {dashboard.custom_module.name: [self.PERMISSION]} }) models.RoleDAO.save(role_dto) context = actions.simple_add_course( self.NO_ACCESS_COURSE_NAME, self.ADMIN_EMAIL, 'Course with no access' ) self.course_without_access = courses.Course(None, context) # pylint: disable=W0212 self.old_nav_mappings = DashboardHandler._nav_mappings # pylint: disable=W0212 DashboardHandler._nav_mappings = {self.ACTION: 'outline'} DashboardHandler.map_action_to_permission( 'get_%s' % self.ACTION, self.PERMISSION) actions.logout()
def test_student_cannot_see_reviews_prematurely(self): """Test that students cannot see others' reviews prematurely.""" email = '*****@*****.**' name = 'Student 1' submission = transforms.dumps([ {'index': 0, 'type': 'regex', 'value': 'S1-1', 'correct': True}, {'index': 1, 'type': 'choices', 'value': 3, 'correct': False}, {'index': 2, 'type': 'regex', 'value': 'is-S1', 'correct': True}, ]) payload = { 'answers': submission, 'assessment_type': LEGACY_REVIEW_UNIT_ID} actions.login(email) actions.register(self, name) response = actions.submit_assessment( self, LEGACY_REVIEW_UNIT_ID, payload) # Student 1 cannot see the reviews for his assignment yet, because he # has not submitted the two required reviews. response = self.get('assessment?name=%s' % LEGACY_REVIEW_UNIT_ID) assert_equals(response.status_int, 200) assert_contains('Due date for this assignment', response.body) assert_contains( 'After you have completed the required number of peer reviews', response.body) actions.logout()
def test_announcements(self): email = '*****@*****.**' actions.login(email, is_admin=True) self._add_announcement({ 'title': 'My Test Title', 'date': '2015/02/03', 'is_draft': False, 'send_email': False, 'html': 'Four score and seven years ago, our founding fathers' }) self._add_announcement({ 'title': 'My Test Title', 'date': '2015/02/03', 'is_draft': True, 'send_email': False, 'html': 'Standing beneath this serene sky, overlooking these', }) response = self.get('dashboard?action=search') index_token = self.get_xsrf_token(response.body, 'gcb-index-course') response = self.post('dashboard?action=index_course', {'xsrf_token': index_token}) self.execute_all_deferred_tasks() # This matches an announcement in the Power Searching course response = self.get( 'search?query=Four%20score%20seven%20years') self.assertIn('gcb-search-result', response.body) self.assertIn('announcements#', response.body) # The draft announcement in Power Searching should not be indexed response = self.get('search?query=Standing%20beneath%20serene') self.assertNotIn('gcb-search-result', response.body) self.assertNotIn('announcements#', response.body)
def setUp(self): super(CertificateCriteriaTestCase, self).setUp() self.base = '/' + self.COURSE_NAME context = actions.simple_add_course(self.COURSE_NAME, self.ADMIN_EMAIL, 'Certificate Criteria') self.old_namespace = namespace_manager.get_namespace() namespace_manager.set_namespace('ns_%s' % self.COURSE_NAME) self.course = courses.Course(None, context) self.course.save() actions.login(self.STUDENT_EMAIL) actions.register(self, self.STUDENT_EMAIL) self.student = ( models.StudentProfileDAO.get_enrolled_student_by_email_for( self.STUDENT_EMAIL, context)) # Override course.yaml settings by patching app_context. self.get_environ_old = sites.ApplicationContext.get_environ self.certificate_criteria = [] def get_environ_new(app_context): environ = self.get_environ_old(app_context) environ['certificate_criteria'] = self.certificate_criteria return environ sites.ApplicationContext.get_environ = get_environ_new
def test_attempt_activity_event(self): """Test activity attempt generates event.""" email = '*****@*****.**' name = 'Test Attempt Activity Event' actions.login(email) actions.register(self, name) # Enable event recording. config.Registry.db_overrides[ lessons.CAN_PERSIST_ACTIVITY_EVENTS.name] = True # Prepare event. request = {} request['source'] = 'test-source' request['payload'] = json.dumps({'Alice': 'Bob'}) # Check XSRF token is required. response = self.post('rest/events?%s' % urllib.urlencode( {'request': json.dumps(request)}), {}) assert_equals(response.status_int, 200) assert_contains('"status": 403', response.body) # Check PUT works. request['xsrf_token'] = XsrfTokenManager.create_xsrf_token( 'event-post') response = self.post('rest/events?%s' % urllib.urlencode( {'request': json.dumps(request)}), {}) assert_equals(response.status_int, 200) assert not response.body # Clean up. config.Registry.db_overrides = {}
def test_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()
def test_single_completed_course(self): """Tests when a single completed course is present.""" email = '*****@*****.**' name = 'Test Assessments' # Register. actions.login(email) actions.register(self, name) response = self.get('/explorer') # Before a course is not completed, # explorer page should not show 'view score' button. assert_does_not_contain('View score', response.body) # Assign a grade to the course enrolled to mark it complete. profile = PersonalProfile.get_by_key_name(email) info = {'final_grade': 'A'} course_info_dict = {'': info} profile.course_info = transforms.dumps(course_info_dict) profile.put() # Check if 'View score' text is visible on profile page. response = self.get('/explorer/profile') assert_contains('View score', response.body) # Check if 'Go to course' button is not visible on explorer page. response = self.get('/explorer') assert_does_not_contain('Go to course', response.body) # Check if 'View score' button is visible on explorer page. response = self.get('/explorer') assert_contains('View score', response.body)
def test_registration_closed(self): """Test student registration when course is full.""" email = '*****@*****.**' name = 'Test Registration Closed' # Override course.yaml settings by patching app_context. get_environ_old = sites.ApplicationContext.get_environ def get_environ_new(self): environ = get_environ_old(self) environ['reg_form']['can_register'] = False return environ sites.ApplicationContext.get_environ = get_environ_new # Try to ogin and register. actions.login(email) try: actions.register(self, name) raise actions.MustFail('Expected to fail.') except actions.MustFail as e: raise e except: pass # Clean up app_context. sites.ApplicationContext.get_environ = get_environ_old
def setUp(self): super(PeerReviewDashboardStudentTest, self).setUp() self.base = '/' + self.COURSE_NAME context = actions.simple_add_course(self.COURSE_NAME, '*****@*****.**', 'Peer Back Button Child') self.course = courses.Course(None, context) self.assessment = self.course.add_assessment() self.assessment.title = 'Assessment' self.assessment.html_content = 'assessment content' self.assessment.workflow_yaml = ( '{grader: human,' 'matcher: peer,' 'review_due_date: \'2034-07-01 12:00\',' 'review_min_count: 1,' 'review_window_mins: 20,' 'submission_due_date: \'2034-07-01 12:00\'}') self.assessment.now_available = True self.course.save() actions.login(self.STUDENT_EMAIL) actions.register(self, self.STUDENT_EMAIL) config.Registry.test_overrides[ utils.CAN_PERSIST_ACTIVITY_EVENTS.name] = True actions.submit_assessment( self, self.assessment.unit_id, { 'answers': '', 'score': 0, 'assessment_type': self.assessment.unit_id }, presubmit_checks=False)
def test_cancel_map_reduce(self): email = '*****@*****.**' actions.login(email, is_admin=True) response = self.get('dashboard?action=peer_review') response = response.forms['gcb-run-visualization-peer_review'].submit( ).follow() # Launch 1st stage of map/reduce job; we must do this in order to # get the pipeline woken up enough to have built a root pipeline # record. Without this, we do not have an ID to use when canceling. self.execute_all_deferred_tasks(iteration_limit=1) # Cancel the job. response = response.forms[ 'gcb-cancel-visualization-peer_review'].submit().follow() assert_contains('Canceled by ' + email, response.body) # Now permit any pending tasks to complete, and expect the job's # status message to remain at "Canceled by ...". # # If the cancel didn't take effect, the map/reduce should have run to # completion and the job's status would change to completed, changing # the message. This is verified in # model_jobs.JobOperationsTest.test_killed_job_can_still_complete self.execute_all_deferred_tasks() response = self.get(response.request.url) assert_contains('Canceled by ' + email, response.body)
def test_tracked_lessons(self): context = actions.simple_add_course('test', '*****@*****.**', 'Test Course') course = courses.Course(None, context) actions.login('*****@*****.**') actions.register(self, 'Some Admin', 'test') with common_utils.Namespace('ns_test'): foo_id = models.LabelDAO.save(models.LabelDTO( None, {'title': 'Foo', 'descripton': 'foo', 'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK})) bar_id = models.LabelDAO.save(models.LabelDTO( None, {'title': 'Bar', 'descripton': 'bar', 'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK})) unit1 = course.add_unit() unit1.now_available = True unit1.labels = str(foo_id) lesson11 = course.add_lesson(unit1) lesson11.objectives = 'common plugh <gcb-youtube videoid="glados">' lesson11.now_available = True lesson11.notes = search_unit_test.VALID_PAGE_URL lesson11.video = 'portal' course.update_unit(unit1) unit2 = course.add_unit() unit2.now_available = True unit1.labels = str(bar_id) lesson21 = course.add_lesson(unit2) lesson21.objectives = 'common plover' lesson21.now_available = True course.update_unit(unit2) course.save() self.index_test_course() # Registered, un-tracked student sees all. response = self.get('/test/search?query=common') self.assertIn('common', response.body) self.assertIn('plugh', response.body) self.assertIn('plover', response.body) response = self.get('/test/search?query=link') # Do see followed links self.assertIn('Partial', response.body) self.assertIn('Absolute', response.body) response = self.get('/test/search?query=lemon') # Do see video refs self.assertIn('v=glados', response.body) # Student with tracks sees filtered view. with common_utils.Namespace('ns_test'): models.Student.set_labels_for_current(str(foo_id)) response = self.get('/test/search?query=common') self.assertIn('common', response.body) self.assertNotIn('plugh', response.body) self.assertIn('plover', response.body) response = self.get('/test/search?query=link') # Links are filtered self.assertNotIn('Partial', response.body) self.assertNotIn('Absolute', response.body) response = self.get('/test/search?query=lemon') # Don't see video refs self.assertNotIn('v=glados', response.body)
def index_test_course(self): email = '*****@*****.**' actions.login(email, is_admin=True) response = self.get('/test/dashboard?action=search') index_token = self.get_xsrf_token(response.body, 'gcb-index-course') response = self.post('/test/dashboard?action=index_course', {'xsrf_token': index_token}) self.execute_all_deferred_tasks()
def test_bad_search(self): email = '*****@*****.**' actions.login(email, is_admin=False) # %3A is a colon, and searching for only punctuation will cause App # Engine's search to throw an error that should be handled response = self.get('search?query=%3A') self.assertEqual(response.status_int, 200) self.assertIn('gcb-search-info', response.body)
def setUp(self): super(CourseOutlineTestCase, self).setUp() actions.login(self.ADMIN_EMAIL, is_admin=True) self.base = '/' + self.COURSE_NAME context = actions.simple_add_course( self.COURSE_NAME, self.ADMIN_EMAIL, 'Outline Testing') self.course = courses.Course(None, context)
def test_non_admin_has_no_access(self): """Test non admin has no access to pages or REST endpoints.""" email = '*****@*****.**' actions.login(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 no access to specific pages and actions. response = self.testapp.get('/admin?action=settings') assert_equals(response.status_int, 302) response = self.testapp.get( '/admin?action=config_edit&name=gcb_admin_user_emails') assert_equals(response.status_int, 302) response = self.testapp.post( '/admin?action=config_reset&name=gcb_admin_user_emails') assert_equals(response.status_int, 302) # Check user has no rights to GET verb. response = self.testapp.get( '/rest/config/item?key=gcb_config_update_interval_sec') assert_equals(response.status_int, 200) json_dict = json.loads(response.body) assert json_dict['status'] == 401 assert json_dict['message'] == 'Access denied.' # Check user has no rights to PUT verb. payload_dict = {} payload_dict['value'] = '666' payload_dict['is_draft'] = False request = {} request['key'] = 'gcb_config_update_interval_sec' request['payload'] = json.dumps(payload_dict) # Check XSRF token is required. response = self.testapp.put('/rest/config/item?%s' % urllib.urlencode( {'request': json.dumps(request)}), {}) assert_equals(response.status_int, 200) assert_contains('"status": 403', response.body) # Check user still has no rights to PUT verb even if he somehow # obtained a valid XSRF token. request['xsrf_token'] = XsrfTokenManager.create_xsrf_token( 'config-property-put') response = self.testapp.put('/rest/config/item?%s' % urllib.urlencode( {'request': json.dumps(request)}), {}) assert_equals(response.status_int, 200) json_dict = json.loads(response.body) assert json_dict['status'] == 401 assert json_dict['message'] == 'Access denied.'
def setUp(self): super(MapReduceSimpleTest, self).setUp() admin_email = '*****@*****.**' self.context = actions.simple_add_course('mr_test', admin_email, 'Test') actions.login(admin_email, is_admin=True) with common_utils.Namespace('ns_mr_test'): # Start range at 1 because 0 is a reserved ID. for key in range(1, DummyEntity.NUM_ENTITIES + 1): DummyDAO.upsert(key, {})
def test_admin_access(self): # 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 the admin site link actions.login('*****@*****.**', is_admin=True) response = self.get('/explorer') assert_contains('Admin Site', response.body)
def test_download_pdf(self): actions.login('*****@*****.**') models.Student.add_new_student_for_current_user( 'Test User', None, self) response = self.get('/certificate.pdf') self.assertEqual('application/pdf', response.headers['Content-Type']) self.assertEqual('attachment; filename=certificate.pdf', response.headers['Content-Disposition']) self.assertIn('/Title (Course Builder Certificate)', response.body)
def test_download_pdf(self): actions.login('*****@*****.**') models.Student.add_new_student_for_current_user('Test User', None, self) response = self.get('/certificate.pdf') self.assertEqual('application/pdf', response.headers['Content-Type']) self.assertEqual( 'attachment; filename=certificate.pdf', response.headers['Content-Disposition']) self.assertIn('/Title (Course Builder Certificate)', response.body)
def test_access_assessment(self): assessment = self.course.add_assessment() assessment.is_draft = True self.course.save() self.assertEquals( self.get('assessment?name=%s' % assessment.unit_id).status_int, 302) actions.login(self.USER_EMAIL, is_admin=False) self.assertEquals( self.get('assessment?name=%s' % assessment.unit_id).status_int, 200) actions.logout()
def setUp(self): super(TestLessonSchema, self).setUp() actions.login(self.ADMIN_EMAIL, is_admin=True) context = actions.simple_add_course( self.COURSE_NAME, self.ADMIN_EMAIL, 'Lesson Course') self.old_namespace = namespace_manager.get_namespace() namespace_manager.set_namespace('ns_%s' % self.COURSE_NAME) self.course = courses.Course(None, context) self.unit = self.course.add_unit() self.course.save()
def setUp(self): super(DashboardCustomNavTestCase, self).setUp() actions.login(self.ADMIN_EMAIL, is_admin=True) self.base = '/' + self.COURSE_NAME context = actions.simple_add_course( self.COURSE_NAME, self.ADMIN_EMAIL, 'Custom Dashboard') self.old_namespace = namespace_manager.get_namespace() namespace_manager.set_namespace('ns_%s' % self.COURSE_NAME) self.course = courses.Course(None, context)
def test_login_and_logout(self): """Test if login and logout behave as expected.""" email = '*****@*****.**' actions.Permissions.assert_logged_out(self) actions.login(email) actions.Permissions.assert_unenrolled(self) actions.logout() actions.Permissions.assert_logged_out(self)
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
def test_course_picker(self): actions.login(self.USER_EMAIL, is_admin=False) picker_options = self._get_all_picker_options() self.assertEquals(len(list(picker_options)), 0) actions.logout() actions.login(self.ADMIN_EMAIL, is_admin=True) picker_options = self._get_all_picker_options() # Expect 3 courses, as the default one is also considered for the picker self.assertEquals(len(picker_options), 2) actions.logout()
def setUp(self): super(TestLessonSchema, self).setUp() actions.login(self.ADMIN_EMAIL, is_admin=True) context = actions.simple_add_course(self.COURSE_NAME, self.ADMIN_EMAIL, 'Lesson Course') self.old_namespace = namespace_manager.get_namespace() namespace_manager.set_namespace('ns_%s' % self.COURSE_NAME) self.course = courses.Course(None, context) self.unit = self.course.add_unit() self.course.save()