示例#1
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))
    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']
示例#3
0
def queue_emails():
    params = request.get_json()
    term_id = params.get('termId')
    section_ids = params.get('sectionIds')
    template_type = params.get('emailTemplateType')

    if term_id and section_ids and template_type:
        section_ids_already_queued = QueuedEmail.get_all_section_ids(
            template_type=template_type, term_id=term_id)
        section_ids_to_queue = [
            id_ for id_ in section_ids if id_ not in section_ids_already_queued
        ]

        for section_id in section_ids_to_queue:
            QueuedEmail.create(section_id=section_id,
                               template_type=template_type,
                               term_id=term_id)

        section_id_count = len(section_ids)
        queued_count = len(section_ids_to_queue)
        if queued_count < section_id_count:
            message = f"""
                {len(section_ids_already_queued)} '{template_type}' emails were already queued up for the
                {'course' if section_id_count == 1 else 'courses'} you submitted.
                Thus, {'no' if queued_count == 0 else f'only {queued_count}'} emails added to the queue.
            """
        else:
            message = f'{queued_count} \'{template_type}\' emails will be sent.'
        return tolerant_jsonify({
            'message': message,
        })
    else:
        raise BadRequestError('Required parameters are missing.')
示例#4
0
    def _room_change_alert(self):
        template_type = 'room_change_no_longer_eligible'
        all_scheduled = list(
            filter(
                lambda s: template_type not in (s.alerts or []),
                Scheduled.get_all_scheduled(term_id=self.term_id),
            ), )
        if all_scheduled:
            email_template = EmailTemplate.get_template_by_type(template_type)
            courses = SisSection.get_courses(
                term_id=self.term_id,
                section_ids=[s.section_id for s in all_scheduled],
                include_deleted=True,
            )
            courses_per_section_id = dict(
                (course['sectionId'], course) for course in courses)
            for scheduled in all_scheduled:
                course = courses_per_section_id.get(scheduled.section_id)
                if course:
                    if self._has_moved_to_ineligible_room(
                            course, scheduled) or course['deletedAt']:
                        if email_template:
                            for instructor in course['instructors']:

                                def _get_interpolate_content(template):
                                    return interpolate_content(
                                        course=course,
                                        publish_type_name=course.get(
                                            'scheduled',
                                            {}).get('publishTypeName'),
                                        recipient_name=instructor['name'],
                                        recording_type_name=course.get(
                                            'scheduled',
                                            {}).get('recordingTypeName'),
                                        templated_string=template,
                                    )

                                QueuedEmail.create(
                                    message=_get_interpolate_content(
                                        email_template.message),
                                    recipient=instructor,
                                    section_id=course['sectionId'],
                                    subject_line=_get_interpolate_content(
                                        email_template.subject_line),
                                    template_type=template_type,
                                    term_id=self.term_id,
                                )
                            Scheduled.add_alert(
                                scheduled_id=course['scheduled']['id'],
                                template_type=template_type)
                        else:
                            send_system_error_email(f"""
                                No '{template_type}' email template available.
                                We are unable to notify {course['label']} instructors of room change.
                            """)
                else:
                    subject = f'Scheduled course has no SIS data (section_id={scheduled.section_id})'
                    message = f'{subject}\n\nScheduled:<pre>{scheduled}</pre>'
                    app.logger.error(message)
                    send_system_error_email(message=message, subject=subject)
    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)
示例#6
0
    def _notify(self, course, template_type):
        email_template = EmailTemplate.get_template_by_type(template_type)
        if email_template:

            def _get_interpolate_content(template):
                scheduled = course.get('scheduled', {})
                return interpolate_content(
                    course=course,
                    publish_type_name=scheduled.get('publishTypeName'),
                    recipient_name=recipient['name'],
                    recording_type_name=scheduled.get('recordingTypeName'),
                    templated_string=template,
                )

            recipient = get_admin_alert_recipient()
            QueuedEmail.create(
                message=_get_interpolate_content(email_template.message),
                recipient=recipient,
                section_id=course['sectionId'],
                subject_line=_get_interpolate_content(
                    email_template.subject_line),
                template_type=template_type,
                term_id=self.term_id,
            )
            Scheduled.add_alert(scheduled_id=course['scheduled']['id'],
                                template_type=template_type)
        else:
            send_system_error_email(f"""
                No email template of type {template_type} is available.
                Diablo admin NOT notified in regard to course {course['label']}.
            """)
    def test_send_invitation_emails(self):
        """Send all email in 'queued_emails' table."""
        def _emails_sent(section_id):
            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']
        courses = [
            {
                'sectionId': 28602,
                'instructorUids': ['234567', '8765432'],
            },
            {
                'sectionId': 28165,
                'instructorUids': ['8765432'],
            },
        ]
        email_template_type = 'invitation'

        for course in courses:
            QueuedEmail.create(course['sectionId'], email_template_type,
                               term_id)
            std_commit(allow_test_environment=True)

        def _get_emails_to_courses():
            emails_sent_ = []
            for course_ in courses:
                emails_sent_.extend(_emails_sent(course_['sectionId']))
            return emails_sent_

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

        # Expect one email per instructor
        emails_sent_after = _get_emails_to_courses()
        assert len(emails_sent_after) == len(emails_sent_before) + 2

        def _find_email(section_id):
            return next((e for e in emails_sent_after
                         if e.section_id == section_id and e.sent_at > before),
                        None)

        for course in courses:
            sent_email = _find_email(section_id=course['sectionId'])
            assert sent_email
            json_ = sent_email.to_api_json()
            assert set(json_['recipientUids']) == set(course['instructorUids'])
            assert json_['sectionId'] == course['sectionId']
            assert json_['templateType'] == email_template_type
            assert json_['termId'] == term_id
            assert json_['sentAt']
示例#8
0
 def email_new_invites(self):
     for course in SisSection.get_courses(term_id=self.term_id):
         if not course['hasOptedOut'] and len(course.get('meetings', {}).get('eligible', [])) == 1:
             for i in course['instructors']:
                 if not i['wasSentInvite']:
                     QueuedEmail.create(
                         recipient=i,
                         section_id=course['sectionId'],
                         template_type='invitation',
                         term_id=self.term_id,
                     )
示例#9
0
    def test_send_invitation_emails(self):
        """Send all email in 'queued_emails' table."""
        term_id = app.config['CURRENT_TERM_ID']
        courses = SisSection.get_courses(section_ids=[50000, 50001],
                                         term_id=term_id)
        email_template_type = 'invitation'

        for course in courses:
            for instructor in course['instructors']:
                QueuedEmail.create(course['sectionId'],
                                   email_template_type,
                                   term_id,
                                   recipient=instructor)
            std_commit(allow_test_environment=True)

        def _get_emails_to_courses():
            emails_sent = []
            for c in courses:
                emails_sent.extend(
                    _get_emails_sent(
                        email_template_type=email_template_type,
                        section_id=c['sectionId'],
                        term_id=term_id,
                    ), )
            return emails_sent

        before = utc_now()
        emails_sent_before = _get_emails_to_courses()
        # Run the job
        QueuedEmailsJob(simply_yield).run()
        std_commit(allow_test_environment=True)

        # Expect one email per instructor
        emails_sent_after = _get_emails_to_courses()
        assert len(emails_sent_after) == len(emails_sent_before) + 3

        def _find_email(section_id, uid):
            return next(
                (e for e in emails_sent_after if e.section_id == section_id
                 and e.sent_at > before and uid == e.recipient_uid), None)

        for course in courses:
            for instructor in course['instructors']:
                sent_email = _find_email(section_id=course['sectionId'],
                                         uid=instructor['uid'])
                assert sent_email
                email_json = sent_email.to_api_json()
                assert email_json['recipientUid'] == instructor['uid']
                assert email_json['sectionId'] == course['sectionId']
                assert email_json['templateType'] == email_template_type
                assert email_json['termId'] == term_id
                assert email_json['sentAt']
示例#10
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)
示例#11
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)
示例#12
0
    def test_currently_no_person_teaching_course(self):
        """Refuse to queue emails for a course without a proper instructor."""
        term_id = app.config['CURRENT_TERM_ID']
        section_id = 50006
        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 creation fails.
        assert not QueuedEmail.create(section_id, email_template_type, term_id, recipient=None)
        assert section_id not in QueuedEmail.get_all_section_ids(template_type=email_template_type, term_id=term_id)
示例#13
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 = 50005
        email_template_type = 'admin_alert_room_change'
        recipient = {
            'name': 'Course Capture Admin',
            'uid': app.config['EMAIL_DIABLO_ADMIN_UID'],
        }
        QueuedEmail.create(section_id,
                           email_template_type,
                           term_id,
                           recipient=recipient)
        std_commit(allow_test_environment=True)

        before = utc_now()
        emails_sent_before = _emails_sent()
        # Run the job
        QueuedEmailsJob(simply_yield).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
        email_json = sent_email.to_api_json()
        assert email_json['recipientUid'] == app.config[
            'EMAIL_DIABLO_ADMIN_UID']
        assert email_json['sectionId'] == section_id
        assert email_json['templateType'] == email_template_type
        assert email_json['termId'] == term_id
        assert email_json['sentAt']
示例#14
0
def queue_emails():
    params = request.get_json()
    term_id = params.get('termId')
    section_id = params.get('sectionId')
    template_type = params.get('emailTemplateType')

    if not (term_id and section_id and template_type):
        raise BadRequestError('Required parameters are missing.')
    course = SisSection.get_course(term_id=term_id, section_id=section_id)
    for instructor in course['instructors']:
        if not QueuedEmail.create(section_id=section_id, recipient=instructor, template_type=template_type, term_id=term_id):
            raise BadRequestError(f"Failed to queue email of type '{template_type}'.")
    return tolerant_jsonify({
        'message': f"An email of type '{template_type}' has been queued.",
    })