Пример #1
0
    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'
Пример #2
0
 def create(
     cls,
     section_id,
     term_id,
     instructor_uids,
     kaltura_schedule_id,
     meeting_days,
     meeting_end_date,
     meeting_end_time,
     meeting_start_date,
     meeting_start_time,
     publish_type_,
     recording_type_,
     room_id,
 ):
     scheduled = cls(
         instructor_uids=instructor_uids,
         kaltura_schedule_id=kaltura_schedule_id,
         meeting_days=meeting_days,
         meeting_end_date=meeting_end_date,
         meeting_end_time=meeting_end_time,
         meeting_start_date=meeting_start_date,
         meeting_start_time=meeting_start_time,
         publish_type_=publish_type_,
         recording_type_=recording_type_,
         room_id=room_id,
         section_id=section_id,
         term_id=term_id,
     )
     db.session.add(scheduled)
     std_commit()
     return scheduled
Пример #3
0
    def test_course_has_opted_out(self):
        """Do not send email to courses that have opted out."""
        def _emails_sent():
            return _get_emails_sent(email_template_type=email_template_type,
                                    section_id=section_id,
                                    term_id=term_id)

        term_id = app.config['CURRENT_TERM_ID']
        section_id = 50000
        CoursePreference.update_opt_out(term_id=term_id,
                                        section_id=section_id,
                                        opt_out=True)
        email_template_type = 'invitation'
        recipient = {
            'name': 'William Peter Blatty',
            'uid': '10001',
        }
        QueuedEmail.create(section_id,
                           email_template_type,
                           term_id,
                           recipient=recipient)
        std_commit(allow_test_environment=True)

        emails_sent_before = _emails_sent()
        # Run the job
        QueuedEmailsJob(simply_yield).run()
        std_commit(allow_test_environment=True)

        # Expect no emails sent
        emails_sent_after = _emails_sent()
        assert len(emails_sent_after) == len(emails_sent_before)
        assert list(map(lambda e: e.id, emails_sent_before)) == list(
            map(lambda e: e.id, emails_sent_after))
Пример #4
0
    def test_scheduled_filter(self, client, admin_session):
        """Scheduled filter: Courses with recordings scheduled."""
        with test_approvals_workflow(app):
            # Send invites
            for section_id in [section_1_id, section_6_id]:
                self._send_invitation_email(section_id)
                self._create_approval(section_id)

            # Feed will only include courses that were scheduled.
            mock_scheduled(
                section_id=section_1_id,
                term_id=self.term_id,
            )
            # Deleted records will be ignored
            mock_scheduled(
                section_id=section_2_id,
                term_id=self.term_id,
            )
            Scheduled.delete(section_id=section_2_id, term_id=self.term_id)
            std_commit(allow_test_environment=True)
            api_json = self._api_courses(client, term_id=self.term_id, filter_='Scheduled')
            assert len(api_json) == 1
            course = _find_course(api_json=api_json, section_id=section_1_id)
            assert course['approvalStatus'] == 'Partially Approved'
            assert course['schedulingStatus'] == 'Scheduled'
            assert not _find_course(api_json=api_json, section_id=section_6_id)
Пример #5
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
Пример #6
0
def add_sis_sections_rows(section):
    instruction_format = section.number.split(' ')[0]
    section_num = section.number.split(' ')[1]
    for instructor in section.instructors:
        instructor_name = f'{instructor.first_name} {instructor.last_name}'
        for meeting in section.meetings:
            days = meeting.days.replace(',', '').replace(' ', '')
            start_date = meeting.start_date.strftime('%Y-%m-%d %H:%M:%S')
            end_date = meeting.end_date.strftime('%Y-%m-%d %H:%M:%S')
            start_time = datetime.strptime(meeting.start_time,
                                           '%I:%M %p').strftime('%H:%M')
            end_time = datetime.strptime(meeting.end_time,
                                         '%I:%M %p').strftime('%H:%M')
            sql = f"""
                INSERT INTO sis_sections (
                    allowed_units, course_name, course_title, created_at, instruction_format, instructor_name,
                    instructor_role_code, instructor_uid, is_primary, meeting_days, meeting_end_date, meeting_end_time,
                    meeting_location, meeting_start_date, meeting_start_time, section_id, section_num, term_id
                )
                SELECT
                    '4', '{section.code}', '{section.title}', now(), '{instruction_format}', '{instructor_name}',
                    '{instructor.role}', '{instructor.uid}', TRUE, '{days}', '{end_date}', '{end_time}',
                    '{meeting.room.name}', '{start_date}', '{start_time}', {section.ccn}, '{section_num}', {section.term.id}
            """
            app.logger.info(sql)
            db.session.execute(text(sql))
            std_commit(allow_test_environment=True)
Пример #7
0
    def test_invited_filter(self, client, admin_session):
        """Invited filter: Course in an eligible room, have received invitation. No approvals. Not scheduled."""
        with test_approvals_workflow(app):
            # Course with approval is NOT expected in results
            self._send_invitation_email(section_5_id)
            self._create_approval(section_5_id)
            # Course in ineligible room is NOT expected in results
            self._send_invitation_email(section_2_id)
            # Course in eligible room
            eligible_section_id = section_4_id
            self._send_invitation_email(eligible_section_id)
            std_commit(allow_test_environment=True)

            api_json = self._api_courses(client, term_id=self.term_id, filter_='Invited')
            assert len(api_json) == 1
            assert api_json[0]['sectionId'] == eligible_section_id

            # Section with ZERO approvals will show up in search results
            course = _find_course(api_json=api_json, section_id=section_4_id)
            assert course
            assert course['label'] == 'CHEM C110L, LAB 001'
            assert course['approvalStatus'] == 'Invited'
            assert course['schedulingStatus'] == 'Not Scheduled'
            # The section with approval will NOT show up in search results
            assert not _find_course(api_json=api_json, section_id=section_5_id)
Пример #8
0
    def test_currently_no_person_teaching_course(self):
        """If course does not have a proper instructor then the email remains queued."""
        def _emails_sent():
            return _get_emails_sent(email_template_type=email_template_type,
                                    section_id=section_id,
                                    term_id=term_id)

        term_id = app.config['CURRENT_TERM_ID']
        section_id = 22460
        email_template_type = 'invitation'
        # Courses with no proper instructor are excluded from query results.
        assert not SisSection.get_course(term_id=term_id,
                                         section_id=section_id)

        queued_email = QueuedEmail.create(section_id, email_template_type,
                                          term_id)
        std_commit(allow_test_environment=True)

        emails_sent_before = _emails_sent()
        # Run the job
        QueuedEmailsJob(app.app_context).run()
        std_commit(allow_test_environment=True)

        # Expect no email sent
        emails_sent_after = _emails_sent()
        assert len(emails_sent_after) == len(emails_sent_before)
        # Assert that email is still queued
        assert section_id in QueuedEmail.get_all_section_ids(
            template_type=email_template_type, term_id=term_id)
        # Clean up
        QueuedEmail.delete(queued_email)
Пример #9
0
    def test_no_email_template_available(self):
        """If email_template is not available then keep related emails in the queue."""
        def _emails_sent():
            return _get_emails_sent(email_template_type=email_template_type,
                                    section_id=section_id,
                                    term_id=term_id)

        term_id = app.config['CURRENT_TERM_ID']
        section_id = 22287
        email_template_type = 'waiting_for_approval'

        queued_email = QueuedEmail.create(section_id, email_template_type,
                                          term_id)
        std_commit(allow_test_environment=True)

        emails_sent_before = _emails_sent()
        # Run the job
        QueuedEmailsJob(app.app_context).run()
        std_commit(allow_test_environment=True)

        # Expect no email sent
        emails_sent_after = _emails_sent()
        assert len(emails_sent_after) == len(emails_sent_before)
        # Assert that email is still queued
        assert section_id in QueuedEmail.get_all_section_ids(
            template_type=email_template_type, term_id=term_id)
        # Clean up
        QueuedEmail.delete(queued_email)
Пример #10
0
    def test_course_has_opted_out(self):
        """Do not send email to courses that have opted out."""
        def _emails_sent():
            return _get_emails_sent(email_template_type=email_template_type,
                                    section_id=section_id,
                                    term_id=term_id)

        term_id = app.config['CURRENT_TERM_ID']
        section_id = 28602
        CoursePreference.update_opt_out(term_id=term_id,
                                        section_id=section_id,
                                        opt_out=True)
        email_template_type = 'invitation'

        QueuedEmail.create(section_id, email_template_type, term_id)
        std_commit(allow_test_environment=True)

        before = utc_now()
        emails_sent_before = _emails_sent()
        # Run the job
        QueuedEmailsJob(app.app_context).run()
        std_commit(allow_test_environment=True)

        # Expect no emails sent
        emails_sent_after = _emails_sent()
        assert len(emails_sent_after) == len(emails_sent_before)
        assert not next(
            (e for e in emails_sent_after
             if e.section_id == section_id and e.sent_at > before), None)
Пример #11
0
    def test_queued_email_for_admin(self):
        """Certain email template types are for admin recipients only."""
        def _emails_sent():
            return _get_emails_sent(email_template_type=email_template_type,
                                    section_id=section_id,
                                    term_id=term_id)

        term_id = app.config['CURRENT_TERM_ID']
        section_id = 22287
        email_template_type = 'admin_alert_room_change'

        QueuedEmail.create(section_id, email_template_type, term_id)
        std_commit(allow_test_environment=True)

        before = utc_now()
        emails_sent_before = _emails_sent()
        # Run the job
        QueuedEmailsJob(app.app_context).run()
        std_commit(allow_test_environment=True)

        # Expect email to admin email address
        emails_sent_after = _emails_sent()
        assert len(emails_sent_after) == len(emails_sent_before) + 1

        sent_email = next(
            (e for e in emails_sent_after
             if e.section_id == section_id and e.sent_at > before), None)
        assert sent_email
        json_ = sent_email.to_api_json()
        assert json_['recipientUids'] == [app.config['EMAIL_DIABLO_ADMIN_UID']]
        assert json_['sectionId'] == section_id
        assert json_['templateType'] == email_template_type
        assert json_['termId'] == term_id
        assert json_['sentAt']
Пример #12
0
    def test_admin_approval(self):
        """Course is scheduled for recording if an admin user has approved."""
        with test_approvals_workflow(app):
            section_id = 22287
            term_id = app.config['CURRENT_TERM_ID']
            course = SisSection.get_course(section_id=section_id,
                                           term_id=term_id)
            instructors = course['instructors']
            assert len(instructors) == 2

            # Verify that course is not scheduled
            assert Scheduled.get_scheduled(section_id=section_id,
                                           term_id=term_id) is None

            Approval.create(
                approved_by_uid=admin_uid,
                approver_type_='admin',
                cross_listed_section_ids=[],
                publish_type_='canvas',
                recording_type_='presentation_audio',
                room_id=Room.find_room('Barker 101').id,
                section_id=section_id,
                term_id=term_id,
            )
            KalturaJob(app.app_context).run()
            std_commit(allow_test_environment=True)
            # Admin approval is all we need.
            assert Scheduled.get_scheduled(section_id=section_id,
                                           term_id=term_id)
Пример #13
0
    def test_opt_out_cross_listings(self, client, admin_session):
        """If a section opts out then its cross-listings are automatically opted out."""
        with test_approvals_workflow(app):
            # First, opt out
            cross_listed_section_ids = [28475, 27950, 32827]
            self._api_opt_out_update(
                client,
                term_id=self.term_id,
                section_id=cross_listed_section_ids[-1],
                opt_out=True,
            )
            section_ids_opted_out = CoursePreference.get_section_ids_opted_out(term_id=self.term_id)
            for section_id in cross_listed_section_ids:
                assert section_id in section_ids_opted_out
            std_commit(allow_test_environment=True)

            # Opt back in
            self._api_opt_out_update(
                client,
                term_id=self.term_id,
                section_id=cross_listed_section_ids[0],
                opt_out=False,
            )
            section_ids_opted_out = CoursePreference.get_section_ids_opted_out(term_id=self.term_id)
            for section_id in cross_listed_section_ids:
                assert section_id not in section_ids_opted_out
Пример #14
0
    def test_has_instructors(self, client, admin_session):
        """Admins can see instructor changes that might disrupt scheduled recordings."""
        with test_approvals_workflow(app):
            meeting_days, meeting_start_time, meeting_end_time = SisSection.get_meeting_times(
                term_id=self.term_id,
                section_id=section_3_id,
            )
            instructor_uids = SisSection.get_instructor_uids(term_id=self.term_id, section_id=section_3_id)
            Scheduled.create(
                cross_listed_section_ids=[],
                instructor_uids=instructor_uids + ['999999'],
                meeting_days=meeting_days,
                meeting_start_time=meeting_start_time,
                meeting_end_time=meeting_end_time,
                publish_type_='canvas',
                recording_type_='presenter_audio',
                room_id=Room.get_room_id(section_id=section_3_id, term_id=self.term_id),
                section_id=section_3_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_3_id)
            assert course
            assert course['scheduled']['hasObsoleteRoom'] is False
            assert course['scheduled']['hasObsoleteMeetingTimes'] is False
            assert course['scheduled']['hasObsoleteInstructors'] is True
Пример #15
0
def mock_scheduled(
    section_id,
    term_id,
    meeting=None,
    override_days=None,
    override_end_date=None,
    override_end_time=None,
    override_room_id=None,
    override_start_date=None,
    override_start_time=None,
    publish_type='kaltura_media_gallery',
    recording_type='presenter_presentation_audio',
):
    meeting = meeting or 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=get_instructor_uids(term_id=term_id,
                                            section_id=section_id),
        kaltura_schedule_id=random.randint(1, 10),
        meeting_days=override_days or meeting['days'],
        meeting_end_date=override_end_date or get_recording_end_date(meeting),
        meeting_end_time=override_end_time or meeting['endTime'],
        meeting_start_date=override_start_date
        or get_recording_start_date(meeting, return_today_if_past_start=True),
        meeting_start_time=override_start_time or meeting['startTime'],
        publish_type_=publish_type,
        recording_type_=recording_type,
        room_id=override_room_id
        or Room.get_room_id(section_id=section_id, term_id=term_id),
        section_id=section_id,
        term_id=term_id,
    )
    std_commit(allow_test_environment=True)
Пример #16
0
    def test_admin_approval(self):
        """Course is scheduled for recording if an admin user has approved."""
        with test_approvals_workflow(app):
            section_id = 50005
            term_id = app.config['CURRENT_TERM_ID']
            course = SisSection.get_course(section_id=section_id,
                                           term_id=term_id)
            instructors = course['instructors']
            assert len(instructors) == 2

            # Verify that course is not scheduled
            assert Scheduled.get_scheduled(section_id=section_id,
                                           term_id=term_id) is None

            Approval.create(
                approved_by_uid=admin_uid,
                approver_type_='admin',
                course_display_name=course['label'],
                publish_type_='kaltura_my_media',
                recording_type_='presentation_audio',
                room_id=Room.find_room('Barker 101').id,
                section_id=section_id,
                term_id=term_id,
            )
            KalturaJob(simply_yield).run()
            std_commit(allow_test_environment=True)
            # Admin approval is all we need.
            assert Scheduled.get_scheduled(section_id=section_id,
                                           term_id=term_id)
Пример #17
0
def change_course_instructor(section,
                             old_instructor=None,
                             new_instructor=None):
    conditional = f" AND instructor_uid = '{old_instructor.uid}'" if old_instructor else ''
    if new_instructor:
        sql = f"""UPDATE sis_sections
                  SET instructor_uid = '{new_instructor.uid}',
                      instructor_name = '{new_instructor.first_name} {new_instructor.last_name}',
                      instructor_role_code = '{new_instructor.role}'
                  WHERE section_id = {section.ccn}
                      AND term_id = {section.term.id}
                      {conditional}
        """
    else:
        sql = f"""UPDATE sis_sections
                  SET instructor_uid = NULL,
                      instructor_name = NULL,
                      instructor_role_code = NULL
                  WHERE section_id = {section.ccn}
                      AND term_id = {section.term.id}
                      AND instructor_uid = '{old_instructor.uid}'
        """
    app.logger.info(sql)
    db.session.execute(text(sql))
    std_commit(allow_test_environment=True)
Пример #18
0
def _create_email_templates():
    EmailTemplate.create(
        template_type='admin_alert_instructor_change',
        name='Alert admin instructor approval needed',
        subject_line='Instructor approval needed',
        message='<code>course.name</code> has new instructor(s).',
    )
    EmailTemplate.create(
        template_type='admin_alert_room_change',
        name='Alert admin when room change',
        subject_line='Room change alert',
        message=
        '<code>course.name</code> has changed to a new room: <code>course.room</code>',
    )
    EmailTemplate.create(
        template_type='notify_instructor_of_changes',
        name='I\'m the Devil. Now kindly undo these straps.',
        subject_line='If you\'re the Devil, why not make the straps disappear?',
        message='That\'s much too vulgar a display of power.',
    )
    EmailTemplate.create(
        template_type='invitation',
        name='What an excellent day for an exorcism.',
        subject_line='You would like that?',
        message='Intensely.',
    )
    EmailTemplate.create(
        template_type='recordings_scheduled',
        name='Recordings scheduled',
        subject_line='Course scheduled for Course Capture',
        message=
        'Recordings of type <code>recording.type</code> will be published to <code>publish.type</code>.',
    )
    std_commit(allow_test_environment=True)
Пример #19
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'
Пример #20
0
def _create_blackouts():
    Blackout.create(
        name='An excellent day for an exorcism',
        start_date='12/25/2021',
        end_date='12/25/2021',
    )
    std_commit(allow_test_environment=True)
Пример #21
0
    def test_not_invited_filter(self, client, admin_session):
        """Not-invited filter: Courses in eligible rooms, never sent an invitation. No approval. Not scheduled."""
        with test_approvals_workflow(app):
            # The first course gets an invitation
            self._send_invitation_email(section_1_id)

            # The second course did not receive an invitation BUT it does have approval.
            invite = SentEmail.get_emails_of_type(
                section_ids=[section_4_id],
                template_type='invitation',
                term_id=self.term_id,
            )
            assert not invite

            self._create_approval(section_4_id)
            std_commit(allow_test_environment=True)
            api_json = self._api_courses(client, term_id=self.term_id, filter_='Not Invited')
            assert not _find_course(api_json=api_json, section_id=section_1_id)
            assert not _find_course(api_json=api_json, section_id=section_4_id)
            # Zero instructors is acceptable
            assert _find_course(api_json=api_json, section_id=eligible_course_with_no_instructors)
            # Third course is in enabled room and has not received an invite. Therefore, it is in the feed.
            assert _is_course_in_enabled_room(section_id=section_3_id, term_id=self.term_id)
            course = _find_course(api_json=api_json, section_id=section_3_id)
            assert course['approvalStatus'] == 'Not Invited'
            assert course['schedulingStatus'] == 'Not Scheduled'
            assert course['label'] == 'BIO 1B, LEC 001'
Пример #22
0
def _create_users():
    for test_user in _test_users:
        user = AdminUser(uid=test_user['uid'])
        db.session.add(user)
        if test_user['deleted_at']:
            AdminUser.delete(user.uid)
    std_commit(allow_test_environment=True)
Пример #23
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
Пример #24
0
def _set_up_and_run_jobs():
    Job.create(job_schedule_type='day_at',
               job_schedule_value='15:00',
               key='kaltura')
    Job.create(job_schedule_type='day_at',
               job_schedule_value='04:30',
               key='queued_emails')
    Job.create(job_schedule_type='day_at',
               job_schedule_value='22:00',
               key='house_keeping')
    Job.create(job_schedule_type='minutes',
               job_schedule_value='120',
               key='instructor_emails')
    Job.create(job_schedule_type='minutes',
               job_schedule_value='120',
               key='invitations')
    Job.create(disabled=True,
               job_schedule_type='minutes',
               job_schedule_value='120',
               key='admin_emails')
    Job.create(job_schedule_type='day_at',
               job_schedule_value='16:00',
               key='canvas')
    Job.create(disabled=True,
               job_schedule_type='minutes',
               job_schedule_value='5',
               key='doomed_to_fail')

    background_job_manager.start(app)
    HouseKeepingJob(app_context=simply_yield).run()
    CanvasJob(app_context=simply_yield).run()
    std_commit(allow_test_environment=True)
Пример #25
0
 def job_finished(cls, id_, failed=False):
     row = cls.query.filter_by(id=id_).first()
     row.failed = failed
     row.finished_at = datetime.now()
     db.session.add(row)
     std_commit()
     return row
Пример #26
0
def _load_courses():
    term_id = app.config['CURRENT_TERM_ID']
    db.session.execute(
        SisSection.__table__.delete().where(SisSection.term_id == term_id))
    save_mock_courses(f"{app.config['FIXTURES_PATH']}/sis/courses.json")
    SisDataRefreshJob.after_sis_data_refresh(term_id=term_id)
    std_commit(allow_test_environment=True)
Пример #27
0
 def update_schedule(cls, job_id, schedule_type, schedule_value):
     job = cls.query.filter_by(id=job_id).first()
     job.job_schedule_type = schedule_type
     job.job_schedule_value = schedule_value
     db.session.add(job)
     std_commit()
     return job
Пример #28
0
    def refresh(cls, term_id):
        # First group section IDs by schedule (time and location)
        sql = f"""
            SELECT
                section_id,
                trim(concat(meeting_days, meeting_end_date, meeting_end_time, meeting_location, meeting_start_date, meeting_start_time)) as schedule
            FROM sis_sections
            WHERE term_id = :term_id
                AND meeting_days <> ''
                AND meeting_end_date <> ''
                AND meeting_end_time <> ''
                AND meeting_location <> ''
                AND meeting_start_date <> ''
                AND meeting_start_time <> ''
        """
        rows = db.session.execute(
            text(sql),
            {
                'term_id': term_id,
            },
        )
        section_ids_per_schedule = {}
        for row in rows:
            schedule = row['schedule']
            if schedule not in section_ids_per_schedule:
                section_ids_per_schedule[schedule] = set()
            section_ids_per_schedule[schedule].add(row['section_id'])

        # Begin refresh by deleting existing rows per term_id
        db.session.execute(cls.__table__.delete().where(cls.term_id == term_id))

        # Next, populate 'cross_listings' table.
        # If section_ids (123, 234, 345) comprise a set of cross-listed section_ids then we construct:
        #   {
        #       123: [234, 345],
        #       234: [123, 345],
        #       345: [123, 234]
        #   }
        # The 'cross_listings' table will get the same three rows.

        cross_listings = {}
        for cross_listed_section_ids in list(section_ids_per_schedule.values()):
            if len(cross_listed_section_ids) > 1:
                for section_id in cross_listed_section_ids:
                    cross_listings[section_id] = [str(id_) for id_ in cross_listed_section_ids if id_ != section_id]

        def chunks(data, chunk_size=500):
            iterator = iter(data)
            for i in range(0, len(data), chunk_size):
                yield {k: data[k] for k in islice(iterator, chunk_size)}

        for cross_listings_chunk in chunks(cross_listings):
            cross_listing_count = len(cross_listings_chunk)
            query = 'INSERT INTO cross_listings (term_id, section_id, cross_listed_section_ids, created_at) VALUES'
            for index, (section_id, cross_listed_section_ids) in enumerate(cross_listings_chunk.items()):
                query += f' (:term_id, {section_id}, ' + "'{" + ', '.join(cross_listed_section_ids) + "}', now())"
                if index < cross_listing_count - 1:
                    query += ','
            db.session.execute(query, {'term_id': term_id})
            std_commit()
Пример #29
0
    def test_refresh_term_data(self):
        """Refreshes term data without duplicate key violation in db."""
        CanvasJob(simply_yield).run()
        std_commit(allow_test_environment=True)

        CanvasJob(simply_yield).run()
        std_commit(allow_test_environment=True)
Пример #30
0
def get_test_section(test_data):
    sql = f"""SELECT sis_sections.section_id AS ccn,
                     sis_sections.course_name AS code,
                     sis_sections.course_title AS title,
                     sis_sections.instruction_format AS format,
                     sis_sections.section_num AS num
                FROM sis_sections
               WHERE sis_sections.term_id = {app.config['CURRENT_TERM_ID']}
                 AND sis_sections.course_name LIKE '{test_data["dept_code"]} %'
                 AND sis_sections.course_name NOT LIKE '{test_data["dept_code"]} C%'
                 AND sis_sections.instruction_format = 'LEC'
                 AND sis_sections.is_principal_listing IS TRUE
                 AND sis_sections.deleted_at IS NULL
            ORDER BY code, ccn
               LIMIT 1;
    """
    app.logger.info(sql)
    result = db.session.execute(text(sql)).first()
    std_commit(allow_test_environment=True)
    app.logger.info(f'{result}')
    sis_data = {
        'ccn': f'{result["ccn"]}',
        'code': result['code'],
        'title': result['title'],
        'number': f'{result["format"]} {result["num"]}',
        'is_primary': 'TRUE',
        'is_primary_listing': True,
    }
    test_data.update(sis_data)
    return Section(test_data)