def test_not_authenticated(self, client): """Deny anonymous access.""" api_get_course( client, term_id=self.term_id, section_id=section_1_id, expected_status_code=401, )
def test_invalid_section_id(self, client, admin_session): """404 if section does not exist.""" api_get_course( client, term_id=self.term_id, section_id=999999, expected_status_code=404, )
def test_deny_deleted_admin_user(self, client, fake_auth): """Deny access if admin user was deleted.""" fake_auth.login(deleted_admin_user_uid) api_get_course( client, term_id=self.term_id, section_id=section_1_id, expected_status_code=401, )
def test_not_authorized(self, client, fake_auth): """Deny access if user is not an admin.""" instructor_uids = get_instructor_uids(section_id=section_1_id, term_id=self.term_id) fake_auth.login(instructor_uids[0]) api_get_course( client, term_id=self.term_id, section_id=section_3_id, expected_status_code=403, )
def test_course_with_partial_approval(self, client, db, admin_session): """Course with two instructors and one approval.""" with test_approvals_workflow(app): # If course has approvals but not scheduled then it will show up in the feed. approved_by_uid = _get_instructor_uids(section_id=section_1_id, term_id=self.term_id)[0] room_id = Room.get_room_id(section_id=section_1_id, term_id=self.term_id) Approval.create( approved_by_uid=approved_by_uid, approver_type_='instructor', cross_listed_section_ids=[], publish_type_='canvas', recording_type_='presentation_audio', room_id=room_id, section_id=section_1_id, term_id=self.term_id, ) std_commit(allow_test_environment=True) api_json = api_get_course( client, term_id=self.term_id, section_id=section_1_id, ) assert [i['uid'] for i in api_json['instructors']] == ['234567', '8765432'] approvals = api_json['approvals'] assert len(approvals) == 1 assert approved_by_uid == approvals[0]['approvedBy']['uid'] assert api_json['room']['id'] == room_id assert api_json['room']['location'] == 'Barrows 106'
def test_authorized_unschedule_scheduled(self, client, admin_session): with test_approvals_workflow(app): api_approve( client, publish_type='kaltura_my_media', recording_type='presentation_audio', section_id=section_1_id, ) mock_scheduled( section_id=section_1_id, term_id=self.term_id, ) course = api_get_course(client, term_id=self.term_id, section_id=section_1_id) assert len(course['approvals']) == 1 assert course['scheduled'] is not None assert course['hasNecessaryApprovals'] is True assert course['hasOptedOut'] is False assert course['schedulingStatus'] == 'Scheduled' response = self._api_unschedule( client, term_id=self.term_id, section_id=section_1_id, ) assert len(response['approvals']) == 0 assert response['scheduled'] is None assert response['hasNecessaryApprovals'] is False assert response['hasOptedOut'] is True assert response['schedulingStatus'] == 'Not Scheduled'
def test_cross_listing(self, client, db, fake_auth): """Course has cross-listings.""" cross_listed_section_ids = {28475, 27950, 32827} instructor_uid = '269246' fake_auth.login(uid=instructor_uid) verified_feed_contents = False for section_id in cross_listed_section_ids: api_json = api_get_course( client, term_id=self.term_id, section_id=section_id, ) # Cross-listed section IDs are expected in API response actual_section_ids = [c['sectionId'] for c in api_json['crossListings']] assert len(actual_section_ids) == 2 assert api_json['sectionId'] not in actual_section_ids if section_id == 27950: assert api_json['label'] == 'IND ENG 195, COL 001' assert api_json['courseTitle'] == 'Richard Newton Lecture Series' assert api_json['meetingDays'] == ['TU'] verified_feed_contents = True assert verified_feed_contents
def test_course_with_partial_approval(self, client, admin_session): """Course with two instructors and one approval.""" with test_approvals_workflow(app): # If course has approvals but not scheduled then it will show up in the feed. approved_by_uid = get_instructor_uids(section_id=section_1_id, term_id=self.term_id)[0] room_id = Room.get_room_id(section_id=section_1_id, term_id=self.term_id) Approval.create( approved_by_uid=approved_by_uid, approver_type_='instructor', publish_type_='kaltura_my_media', recording_type_='presentation_audio', room_id=room_id, section_id=section_1_id, term_id=self.term_id, ) std_commit(allow_test_environment=True) api_json = api_get_course( client, term_id=self.term_id, section_id=section_1_id, ) assert [i['uid'] for i in api_json['instructors']] == ['10001', '10002'] approvals = api_json['approvals'] assert len(approvals) == 1 assert approved_by_uid == approvals[0]['approvedBy']['uid'] assert api_json['approvalStatus'] == 'Partially Approved' assert api_json['schedulingStatus'] == 'Not Scheduled' assert api_json['meetings']['eligible'][0]['room']['id'] == room_id assert api_json['meetings']['eligible'][0]['room']['location'] == 'Barrows 106'
def test_no_instructors(self, client, admin_session): """Course with no instructors should be available.""" api_json = api_get_course( client, term_id=self.term_id, section_id=eligible_course_with_no_instructors, ) assert len(api_json['instructors']) == 0
def test_section_with_canvas_course_sites(self, client, db, admin_session): """Canvas course site information is included in the API.""" api_json = api_get_course( client, term_id=self.term_id, section_id=section_with_canvas_course_sites, ) assert len(api_json['canvasCourseSites']) == 3
def _verify_name_generation(self, client, section_id, expected_name): # section_id = self._create_cross_listed(courses=courses) api_json = api_get_course( client, section_id=section_id, term_id=self.term_id, ) assert api_json['label'] == expected_name, f'Failed on section_id={section_id}' cross_listings = api_json['crossListings'] assert len(cross_listings) >= 1 api_get_course( client, section_id=cross_listings[0]['sectionId'], term_id=self.term_id, expected_status_code=404, )
def test_no_cross_listing(self, client, admin_session): """Course does not have cross-listing.""" api_json = api_get_course( client, term_id=self.term_id, section_id=section_2_id, ) assert len(api_json['crossListings']) == 0
def test_approval_by_instructors(self, app, client, fake_auth): """Instructor can submit approval if s/he is teaching the requested course.""" with test_approvals_workflow(app): instructor_uids = get_instructor_uids(section_id=section_1_id, term_id=self.term_id) fake_auth.login(instructor_uids[0]) api_approve( client, publish_type='kaltura_my_media', recording_type='presentation_audio', section_id=section_1_id, ) std_commit(allow_test_environment=True) fake_auth.login(instructor_uids[1]) api_approve( client, publish_type='kaltura_media_gallery', recording_type='presentation_audio', section_id=section_1_id, ) std_commit(allow_test_environment=True) QueuedEmailsJob(app.app_context).run() # First instructor was notified 1) that second instructor needed to approve; 2) that second instructor made changes. emails_sent = SentEmail.get_emails_sent_to(instructor_uids[0]) assert len(emails_sent) == 2 for email in emails_sent: assert email.section_id == section_1_id assert email.term_id == self.term_id assert emails_sent[0].template_type == 'waiting_for_approval' assert emails_sent[1].template_type == 'notify_instructor_of_changes' # Second instructor received no notifications. assert len(SentEmail.get_emails_sent_to(instructor_uids[1])) == 0 fake_auth.login(admin_uid) api_json = api_get_course( client, term_id=self.term_id, section_id=section_1_id, ) assert api_json['meetings']['eligible'][0]['room']['location'] == 'Barrows 106' instructor_uids = [i['uid'] for i in api_json['instructors']] assert instructor_uids == instructor_uids approvals_ = api_json['approvals'] assert len(approvals_) == 2 assert approvals_[0]['approvedBy']['uid'] == instructor_uids[0] assert approvals_[0]['publishType'] == 'kaltura_my_media' assert approvals_[1]['approvedBy']['uid'] == instructor_uids[1] assert approvals_[1]['publishType'] == 'kaltura_media_gallery' assert approvals_[1]['recordingType'] == 'presentation_audio' assert approvals_[1]['recordingTypeName'] == 'Presentation and Audio' assert api_json['hasNecessaryApprovals'] is True assert api_json['scheduled'] is None
def test_li_ka_shing_recording_options(self, client, admin_session): """Rooms designated as 'auditorium' offer ALL types of recording.""" api_json = api_get_course( client, term_id=self.term_id, section_id=section_3_id, ) assert api_json['meetings']['eligible'][0]['room']['location'] == 'Li Ka Shing 145' assert len(api_json['meetings']['eligible'][0]['room']['recordingTypeOptions']) == 3
def test_cross_listing(self, client, fake_auth): """Course has cross-listings.""" section_id = 50007 cross_listed_section_ids = {50008, 50009} instructor_uid = '10008' fake_auth.login(uid=instructor_uid) api_json = api_get_course( client, term_id=self.term_id, section_id=section_id, ) assert cross_listed_section_ids == set([c['sectionId'] for c in api_json['crossListings']]) # Verify that cross-listed section_ids have been "deleted" in sis_sections table for section_id_ in cross_listed_section_ids: api_get_course( client, term_id=self.term_id, section_id=section_id_, expected_status_code=404, )
def test_scheduling_removes_opt_out(self, client, admin_session): with test_approvals_workflow(app): self._api_opt_out_update( client, term_id=self.term_id, section_id=section_1_id, opt_out=True, ) api_json = api_get_course(client, section_id=section_1_id, term_id=self.term_id) assert api_json['schedulingStatus'] == 'Not Scheduled' assert api_json['hasOptedOut'] is True api_approve( client, publish_type='kaltura_my_media', recording_type='presentation_audio', section_id=section_1_id, ) api_json = api_get_course(client, section_id=section_1_id, term_id=self.term_id) assert api_json['schedulingStatus'] == 'Queued for Scheduling' assert api_json['hasOptedOut'] is False
def test_date_time_format(self, client, db, fake_auth): """Dates and times are properly formatted for front-end display.""" instructor_uids = _get_instructor_uids(section_id=section_2_id, term_id=self.term_id) fake_auth.login(instructor_uids[0]) api_json = api_get_course( client, term_id=self.term_id, section_id=section_2_id, ) assert api_json['meetingDays'] == ['MO', 'WE', 'FR'] assert api_json['meetingStartTime'] == '3:00 pm' assert api_json['meetingEndTime'] == '3:59 pm' assert api_json['meetingLocation'] == 'Wheeler 150'
def test_meeting_recording_end_date(self, client, admin_session): # The term ends on a Tuesday with override_config(app, 'CURRENT_TERM_END', '2020-11-24'): api_json = api_get_course( client, term_id=self.term_id, section_id=50015, ) assert api_json['meetings']['eligible'][0]['endDate'] == '2020-12-11' # The course meets on ['MO', 'WE', 'FR']. The last recordings is on Wed preceding term_end assert api_json['meetings']['eligible'][0]['recordingEndDate'] == '2020-11-23' assert api_json['meetings']['ineligible'][0]['endDate'] == '2020-12-11' assert 'recordingEndDate' not in api_json['meetings']['ineligible'][0]
def test_approval_by_instructors(self, client, db, fake_auth): """Instructor can submit approval if s/he is teaching the requested course.""" instructor_uids = _get_instructor_uids(section_id=section_1_id, term_id=self.term_id) fake_auth.login(instructor_uids[0]) api_approve( client, publish_type='canvas', recording_type='presentation_audio', section_id=section_1_id, ) std_commit(allow_test_environment=True) fake_auth.login(instructor_uids[1]) api_approve( client, publish_type='kaltura_media_gallery', recording_type='presentation_audio', section_id=section_1_id, ) std_commit(allow_test_environment=True) for uid in ('234567', '8765432'): emails_sent = SentEmail.get_emails_sent_to(uid) assert len(emails_sent) > 0 most_recent = emails_sent[-1] assert most_recent.section_id == section_1_id assert most_recent.template_type == 'notify_instructor_of_changes' assert most_recent.term_id == self.term_id fake_auth.login(admin_uid) api_json = api_get_course( client, term_id=self.term_id, section_id=section_1_id, ) assert api_json['room']['location'] == 'Barrows 106' instructor_uids = [i['uid'] for i in api_json['instructors']] assert instructor_uids == instructor_uids approvals_ = api_json['approvals'] assert len(approvals_) == 2 assert approvals_[0]['approvedBy']['uid'] == instructor_uids[0] assert approvals_[0]['publishType'] == 'canvas' assert approvals_[1]['approvedBy']['uid'] == instructor_uids[1] assert approvals_[1]['publishType'] == 'kaltura_media_gallery' assert approvals_[1]['recordingType'] == 'presentation_audio' assert approvals_[1]['recordingTypeName'] == 'Presentation and Audio' assert api_json['hasNecessaryApprovals'] is True assert api_json['scheduled'] is None
def test_date_time_format(self, client, fake_auth): """Dates and times are properly formatted for front-end display.""" instructor_uids = get_instructor_uids(section_id=section_2_id, term_id=self.term_id) fake_auth.login(instructor_uids[0]) api_json = api_get_course( client, term_id=self.term_id, section_id=section_2_id, ) assert api_json['meetings']['ineligible'][0]['daysFormatted'] == ['MO', 'WE', 'FR'] assert api_json['meetings']['ineligible'][0]['startTimeFormatted'] == '3:00 pm' assert api_json['meetings']['ineligible'][0]['endTimeFormatted'] == '3:59 pm' assert api_json['meetings']['ineligible'][0]['location'] == 'Wheeler 150' assert api_json['nonstandardMeetingDates'] is False assert api_json['meetingType'] == 'A'
def test_dual_mode_instruction(self, client, admin_session): """Course is both online and in a physical location.""" api_json = api_get_course( client, term_id=self.term_id, section_id=50014, ) eligible_meetings = api_json['meetings']['eligible'] ineligible_meetings = api_json['meetings']['ineligible'] assert len(eligible_meetings) == 1 assert len(ineligible_meetings) == 2 assert eligible_meetings[0]['location'] == 'Barker 101' assert ineligible_meetings[0]['location'] == 'Internet/Online' assert ineligible_meetings[1]['location'] == 'Dwinelle 155' assert ineligible_meetings[0]['startDate'] < ineligible_meetings[1]['startDate'] assert api_json['nonstandardMeetingDates'] is True assert api_json['meetingType'] == 'C'
def test_instructor_of_cross_listing(self, client, fake_auth): """If section X and Y are cross-listed then /course page of X must be reachable by instructor of Y.""" section_id = 50012 cross_listed_section_id = 50013 instructor_uid = '10010' # Confirm that cross-listed section was deleted during sis_data_refresh job assert not SisSection.get_course(section_id=cross_listed_section_id, term_id=self.term_id) # Log in as instructor of cross-listed section fake_auth.login(uid=instructor_uid) api_json = api_get_course( client, term_id=self.term_id, section_id=section_id, ) assert len(api_json['crossListings']) == 1 assert cross_listed_section_id == api_json['crossListings'][0]['sectionId'] assert instructor_uid in [i['uid'] for i in api_json['instructors']]
def test_hybrid_instruction(self, client, admin_session): """Course exists in two concurrent physical locations.""" api_json = api_get_course( client, term_id=self.term_id, section_id=50015, ) eligible_meetings = api_json['meetings']['eligible'] ineligible_meetings = api_json['meetings']['ineligible'] assert len(eligible_meetings) == 1 assert len(ineligible_meetings) == 1 assert eligible_meetings[0]['startDate'] == ineligible_meetings[0]['startDate'] assert api_json['nonstandardMeetingDates'] is False assert eligible_meetings[0]['location'] == 'Barker 101' assert eligible_meetings[0]['eligible'] is True assert ineligible_meetings[0]['location'] == 'LeConte 1' assert ineligible_meetings[0]['eligible'] is False assert api_json['meetingType'] == 'B'