Example #1
0
 def _send_invitation_email(self, section_id):
     SentEmail.create(
         section_id=section_id,
         recipient_uid=get_instructor_uids(section_id=section_id, term_id=self.term_id)[0],
         template_type='invitation',
         term_id=self.term_id,
     )
Example #2
0
    def test_has_obsolete_meeting_dates(self, client, admin_session):
        """Admins can see meeting date changes that might disrupt scheduled recordings."""
        with test_approvals_workflow(app):
            meeting = get_eligible_meeting(section_id=section_1_id, term_id=self.term_id)
            obsolete_meeting_end_date = '2020-04-01'
            assert meeting['endDate'] != obsolete_meeting_end_date

            Scheduled.create(
                instructor_uids=get_instructor_uids(term_id=self.term_id, section_id=section_1_id),
                kaltura_schedule_id=random.randint(1, 10),
                meeting_days=meeting['days'],
                meeting_end_date=obsolete_meeting_end_date,
                meeting_end_time=meeting['endTime'],
                meeting_start_date=meeting['startDate'],
                meeting_start_time=meeting['startTime'],
                publish_type_='kaltura_my_media',
                recording_type_='presentation_audio',
                room_id=Room.get_room_id(section_id=section_1_id, term_id=self.term_id),
                section_id=section_1_id,
                term_id=self.term_id,
            )
            std_commit(allow_test_environment=True)

            api_json = self._api_course_changes(client, term_id=self.term_id)
            course = _find_course(api_json=api_json, section_id=section_1_id)
            assert course
            assert course['scheduled']['hasObsoleteRoom'] is False
            assert course['scheduled']['hasObsoleteDates'] is True
            assert course['scheduled']['hasObsoleteTimes'] is False
            assert course['scheduled']['hasObsoleteInstructors'] is False
Example #3
0
    def test_has_obsolete_instructors(self, client, admin_session):
        """Admins can see instructor changes that might disrupt scheduled recordings."""
        with test_approvals_workflow(app):
            meeting = get_eligible_meeting(section_id=section_1_id, term_id=self.term_id)
            instructor_uids = get_instructor_uids(term_id=self.term_id, section_id=section_1_id)
            # Course has multiple instructors; we will schedule using only one instructor UID.
            assert len(instructor_uids) > 1
            scheduled_with_uid = instructor_uids[0]
            Scheduled.create(
                instructor_uids=[scheduled_with_uid],
                kaltura_schedule_id=random.randint(1, 10),
                meeting_days=meeting['days'],
                meeting_end_date=get_recording_end_date(meeting),
                meeting_end_time=meeting['endTime'],
                meeting_start_date=get_recording_start_date(meeting, return_today_if_past_start=True),
                meeting_start_time=meeting['startTime'],
                publish_type_='kaltura_my_media',
                recording_type_='presenter_audio',
                room_id=Room.get_room_id(section_id=section_1_id, term_id=self.term_id),
                section_id=section_1_id,
                term_id=self.term_id,
            )
            std_commit(allow_test_environment=True)

            api_json = self._api_course_changes(client, term_id=self.term_id)
            course = _find_course(api_json=api_json, section_id=section_1_id)
            assert course
            assert course['scheduled']['hasObsoleteRoom'] is False
            assert course['scheduled']['hasObsoleteDates'] is False
            assert course['scheduled']['hasObsoleteTimes'] is False
            assert course['scheduled']['hasObsoleteInstructors'] is True
            assert len(course['instructors']) == 2
            assert len(course['scheduled']['instructors']) == 1
            assert course['scheduled']['instructors'][0]['uid'] == scheduled_with_uid
Example #4
0
    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'
Example #5
0
    def test_admin_alert_multiple_meeting_patterns(self):
        """Emails admin if course is scheduled with weird start/end dates."""
        with test_approvals_workflow(app):
            with enabled_job(job_key=AdminEmailsJob.key()):
                term_id = app.config['CURRENT_TERM_ID']
                section_id = 50014
                room_id = Room.find_room('Barker 101').id
                # The course has two instructors.
                instructor_uid = get_instructor_uids(section_id=section_id,
                                                     term_id=term_id)[0]
                approval = Approval.create(
                    approved_by_uid=instructor_uid,
                    approver_type_='instructor',
                    publish_type_='kaltura_my_media',
                    recording_type_='presenter_audio',
                    room_id=room_id,
                    section_id=section_id,
                    term_id=term_id,
                )
                # Uh oh! Only one of them has been scheduled.
                meeting = get_eligible_meeting(section_id=section_id,
                                               term_id=term_id)
                Scheduled.create(
                    instructor_uids=[instructor_uid],
                    kaltura_schedule_id=random.randint(1, 10),
                    meeting_days=meeting['days'],
                    meeting_end_date=get_recording_end_date(meeting),
                    meeting_end_time=meeting['endTime'],
                    meeting_start_date=get_recording_start_date(
                        meeting, return_today_if_past_start=True),
                    meeting_start_time=meeting['startTime'],
                    publish_type_=approval.publish_type,
                    recording_type_=approval.recording_type,
                    room_id=room_id,
                    section_id=section_id,
                    term_id=term_id,
                )
                courses = SisSection.get_courses_scheduled_nonstandard_dates(
                    term_id=term_id)
                course = next(
                    (c for c in courses if c['sectionId'] == section_id), None)
                assert course

                # Message queued but not sent.
                admin_uid = app.config['EMAIL_DIABLO_ADMIN_UID']
                AdminEmailsJob(simply_yield).run()
                queued_messages = QueuedEmail.query.filter_by(
                    section_id=section_id).all()
                assert len(queued_messages) == 1
                for queued_message in queued_messages:
                    assert '2020-08-26 to 2020-10-02' in queued_message.message

                # Message sent.
                QueuedEmailsJob(simply_yield).run()
                emails_sent = SentEmail.get_emails_sent_to(uid=admin_uid)
                assert len(emails_sent) == 1
                assert emails_sent[
                    0].template_type == 'admin_alert_multiple_meeting_patterns'
                assert emails_sent[0].section_id == section_id
Example #6
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_alert_admin_of_instructor_change(self):
     """Emails admin when a scheduled course gets a new instructor."""
     with test_approvals_workflow(app):
         with enabled_job(job_key=AdminEmailsJob.key()):
             term_id = app.config['CURRENT_TERM_ID']
             section_id = 50005
             room_id = Room.find_room('Barker 101').id
             # The course has two instructors.
             instructor_1_uid, instructor_2_uid = get_instructor_uids(
                 section_id=section_id, term_id=term_id)
             approval = Approval.create(
                 approved_by_uid=instructor_1_uid,
                 approver_type_='instructor',
                 course_display_name=
                 f'term_id:{term_id} section_id:{section_id}',
                 publish_type_='kaltura_my_media',
                 recording_type_='presenter_audio',
                 room_id=room_id,
                 section_id=section_id,
                 term_id=term_id,
             )
             # Uh oh! Only one of them has been scheduled.
             meeting = get_eligible_meeting(section_id=section_id,
                                            term_id=term_id)
             Scheduled.create(
                 course_display_name=
                 f'term_id:{term_id} section_id:{section_id}',
                 instructor_uids=[instructor_1_uid],
                 kaltura_schedule_id=random.randint(1, 10),
                 meeting_days=meeting['days'],
                 meeting_end_date=get_recording_end_date(meeting),
                 meeting_end_time=meeting['endTime'],
                 meeting_start_date=get_recording_start_date(
                     meeting, return_today_if_past_start=True),
                 meeting_start_time=meeting['startTime'],
                 publish_type_=approval.publish_type,
                 recording_type_=approval.recording_type,
                 room_id=room_id,
                 section_id=section_id,
                 term_id=term_id,
             )
             admin_uid = app.config['EMAIL_DIABLO_ADMIN_UID']
             email_count = _get_email_count(admin_uid)
             # Message queued but not sent.
             AdminEmailsJob(simply_yield).run()
             assert _get_email_count(admin_uid) == email_count
             queued_messages = QueuedEmail.query.filter_by(
                 template_type='admin_alert_instructor_change').all()
             assert len(queued_messages) == 1
             for snippet in [
                     'LAW 23', 'Old instructor(s) Regan MacNeil',
                     'New instructor(s) Regan MacNeil, Burke Dennings'
             ]:
                 assert snippet in queued_messages[0].message
             # Message sent.
             QueuedEmailsJob(simply_yield).run()
             assert _get_email_count(admin_uid) == email_count + 1
Example #8
0
 def test_unauthorized(self, client, fake_auth):
     """Instructors cannot unschedule courses."""
     instructor_uids = get_instructor_uids(section_id=section_1_id, term_id=self.term_id)
     fake_auth.login(instructor_uids[0])
     self._api_unschedule(
         client,
         term_id=self.term_id,
         section_id=section_1_id,
         expected_status_code=401,
     )
Example #9
0
 def _create_approval(self, section_id):
     Approval.create(
         approved_by_uid=get_instructor_uids(section_id=section_id, term_id=self.term_id)[0],
         approver_type_='instructor',
         publish_type_='kaltura_my_media',
         recording_type_='presentation_audio',
         room_id=Room.get_room_id(section_id=section_id, term_id=self.term_id),
         section_id=section_id,
         term_id=self.term_id,
     )
Example #10
0
 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,
     )
Example #11
0
 def test_unauthorized(self, client, fake_auth):
     """Instructors cannot modify preferences."""
     instructor_uids = get_instructor_uids(section_id=section_1_id, term_id=self.term_id)
     fake_auth.login(instructor_uids[0])
     self._api_opt_out_update(
         client,
         term_id=self.term_id,
         section_id=section_1_id,
         opt_out=True,
         expected_status_code=401,
     )
Example #12
0
    def test_instructor_already_approved(self, client, fake_auth):
        """Instructor can submit his/her approval only once."""
        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])

            for expected_status_code in [200, 403]:
                api_approve(
                    client,
                    publish_type='kaltura_my_media',
                    recording_type='presentation_audio',
                    section_id=section_1_id,
                    expected_status_code=expected_status_code,
                )
Example #13
0
 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'
Example #14
0
    def test_alert_admin_of_room_change(self, db_session):
        """Emails admin when a scheduled course gets a room change."""
        with test_approvals_workflow(app):
            with enabled_job(job_key=AdminEmailsJob.key()):
                term_id = app.config['CURRENT_TERM_ID']
                section_id = 50004
                approved_by_uid = '10004'
                the_old_room = 'Wheeler 150'
                scheduled_in_room = Room.find_room(the_old_room)
                approval = Approval.create(
                    approved_by_uid=approved_by_uid,
                    approver_type_='instructor',
                    publish_type_='kaltura_media_gallery',
                    recording_type_='presenter_audio',
                    room_id=scheduled_in_room.id,
                    section_id=section_id,
                    term_id=term_id,
                )
                meeting = get_eligible_meeting(section_id=section_id,
                                               term_id=term_id)
                Scheduled.create(
                    instructor_uids=get_instructor_uids(term_id=term_id,
                                                        section_id=section_id),
                    kaltura_schedule_id=random.randint(1, 10),
                    meeting_days=meeting['days'],
                    meeting_end_date=get_recording_end_date(meeting),
                    meeting_end_time=meeting['endTime'],
                    meeting_start_date=get_recording_start_date(
                        meeting, return_today_if_past_start=True),
                    meeting_start_time=meeting['startTime'],
                    publish_type_=approval.publish_type,
                    recording_type_=approval.recording_type,
                    room_id=scheduled_in_room.id,
                    section_id=section_id,
                    term_id=term_id,
                )

                admin_uid = app.config['EMAIL_DIABLO_ADMIN_UID']
                # Message queued, then sent.
                AdminEmailsJob(simply_yield).run()
                QueuedEmailsJob(simply_yield).run()
                emails_sent = SentEmail.get_emails_sent_to(uid=admin_uid)
                assert len(emails_sent) == 1
                assert emails_sent[0].section_id == section_id
                assert emails_sent[
                    0].template_type == 'admin_alert_room_change'
Example #15
0
    def test_partially_approved_filter(self, client, admin_session):
        """Partially approved: Eligible, invited course with 1+ approvals, but not ALL instructors have approved."""
        with test_approvals_workflow(app):
            for section_id in [section_1_id, section_6_id, section_7_id]:
                # Assert multiple instructors
                assert len(get_instructor_uids(section_id=section_id, term_id=self.term_id)) > 1
                # Send invites
                self._send_invitation_email(section_id)
                if section_id == section_1_id:
                    # If course is "approved" by admin only then it will NOT show up on the partially-approval list.
                    Approval.create(
                        approved_by_uid=admin_uid,
                        approver_type_='admin',
                        publish_type_='kaltura_my_media',
                        recording_type_='presentation_audio',
                        room_id=Room.get_room_id(section_id=section_id, term_id=self.term_id),
                        section_id=section_id,
                        term_id=self.term_id,
                    )
                else:
                    # Approval by first instructor only
                    self._create_approval(section_id)

            # Feed will include both scheduled and not scheduled.
            for section_id in [section_1_id, section_7_id]:
                mock_scheduled(section_id=section_id, term_id=self.term_id)

            # Unschedule one of them
            Approval.delete(section_id=section_7_id, term_id=self.term_id)
            Scheduled.delete(section_id=section_7_id, term_id=self.term_id)

            std_commit(allow_test_environment=True)
            api_json = self._api_courses(client, term_id=self.term_id, filter_='Partially Approved')
            assert len(api_json) == 1
            course = _find_course(api_json=api_json, section_id=section_6_id)
            assert course
            assert course['label'] == 'LAW 23, LEC 002'
            assert course['approvalStatus'] == 'Partially Approved'
            assert course['schedulingStatus'] == 'Not Scheduled'
Example #16
0
 def test_unauthorized(self, client, fake_auth):
     """Instructors cannot view courses report."""
     instructor_uids = get_instructor_uids(section_id=section_1_id, term_id=self.term_id)
     fake_auth.login(instructor_uids[0])
     self._api_courses_report(client, term_id=self.term_id, expected_status_code=401)
Example #17
0
 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=app.config['CURRENT_TERM_ID'])
     fake_auth.login(instructor_uids[0])
     self._api_courses_csv(client, expected_status_code=401)
Example #18
0
 def test_not_authorized(self, client, fake_auth):
     instructor_uids = get_instructor_uids(section_id=section_1_id, term_id=self.term_id)
     fake_auth.login(instructor_uids[0])
     self._api_courses(client, term_id=self.term_id, expected_status_code=401)