def test_check_course_assignment_notifications_old_assignment(
            self, time, send_warnings, get_assignments, status, enrolled_users,
            update, check_if_ended):
        """Test with more than a day old notification, which should be skipped"""
        # Init scheduler
        sched = get_test_scheduler()

        # Init course
        make_test_course()

        deadline_manager.check_course_assignment_notifications(2, sched)

        send_warnings.assert_not_called()

        assignments_to_check_on_update = []
        update.assert_called_with(2, sched, assignments_to_check_on_update)

        # Test when already sent
        assignments_sent = AssignmentNotificationSent('6early', 6, 'early',
                                                      datetime.today())
        assignments_sent.save()
        assignments_sent = AssignmentNotificationSent('9early', 9, 'early',
                                                      datetime.today())
        assignments_sent.save()
        deadline_manager.check_course_assignment_notifications(2, sched)

        send_warnings.assert_not_called()

        assignments_to_check_on_update = []
        update.assert_called_with(2, sched, assignments_to_check_on_update)
Esempio n. 2
0
    def test_get_course_from_db(self, print_mock):
        # Test without a course in the database
        result1 = utils.get_course_from_db(2)
        print_mock.assert_called_with("Course: 2 could not be found in Course when searched in get_course_from_db")
        print_mock.assert_called_once()

        self.assertIs(result1, None)

        # Test with course in the database
        make_test_course(course_id=2)
        result2 = utils.get_course_from_db(2)

        self.assertEqual(len(Course.objects.filter(courseId=2)), 1)
        self.assertEqual(result2, Course.objects.get(courseId=2))
    def test_get_time_before_deadline(self, print_mock):
        # Test without a course in the database
        result = deadline_manager.get_time_before_deadline(2)
        print_mock.assert_called_with(
            "Course: 2 could not be found in Course when searched in get_course_from_db"
        )
        print_mock.assert_called_once()

        self.assertIs(result, None)

        # Test with course
        make_test_course()

        result = deadline_manager.get_time_before_deadline(2)

        self.assertEqual(result, 24 * 3600)
    def test_update_first_assignment_notification_time_all_courses_without_mock(
            self, time, reschedule, get_assignments, on_save_course,
            check_if_ended):
        # Init
        sched = get_test_scheduler()
        dt_of_deadline = datetime.fromtimestamp(1573776060)
        dt_of_early = datetime.fromtimestamp(1573776060 - 86400)
        course = make_test_course()
        course.deadline = True
        course.save()

        FirstAssignmentOfCourse(course_id=2,
                                assignment_id=6,
                                notification_type='late',
                                time=None).save()

        # Run method
        deadline_manager.update_first_assignment_notification_time_all_courses(
            sched)

        # Assert
        reschedule.assert_called_with('2assignment_check', 'date',
                                      {'run_date': dt_of_early}, dt_of_early)
        reschedule.assert_called_once()
        self.assertEqual(len(FirstAssignmentOfCourse.objects.all()), 1)
        self.assertEqual(
            FirstAssignmentOfCourse.objects.get(course_id=2).time, dt_of_early)
    def test_update_first_assignment_notification_time_all_courses_with_mock(
            self, update_first_of_course, on_save_course,
            remove_outdated_db_assignment_entries, check_if_ended):
        # Init scheduler
        sched = get_test_scheduler()

        # Init test data and corrisponding expected calls
        test_course_ids = [1, 2, 5, 10]
        expected_calls = []
        for c_id in test_course_ids:
            FirstAssignmentOfCourse(course_id=c_id,
                                    assignment_id=c_id + 10,
                                    notification_type='late',
                                    time=None).save()
            course = make_test_course(c_id, 24 * c_id)
            course.deadline = True
            course.save()

            expected_calls.append(call(c_id, sched))

        # Run method
        deadline_manager.update_first_assignment_notification_time_all_courses(
            sched)

        # Assert results
        update_first_of_course.assert_has_calls(expected_calls)
        remove_outdated_db_assignment_entries.assert_called_once()
        def test_check_course_assignment_notifications_course_ended(
                self, time, get_assignments, check_if_ended, send_single,
                update_first):
            sched = get_test_scheduler()
            make_test_course()

            # Add deadline notification job
            sched.add_deadline_notification(2)
            # Force job because scheduler is paused while testing
            deadline_manager.check_course_assignment_notifications(2, sched)

            # Assert that nothing was called because the course has already ended
            send_single.assert_not_called()
            update_first.assert_not_called()

            # Assert that the job has been removed
            self.assertNotIn('2assignment_check', sched.jobs)
            self.assertEqual(list(CronJob.objects.filter(course=2)), [])
            self.assertEqual(len(FirstAssignmentOfCourse.objects.all()), 0)
    def test_check_course_assignment_notifications_early(
            self, time, send_warnings, get_assignments, status, enrolled_users,
            update, check_if_ended):
        """Test early notification check"""
        # Init scheduler
        sched = get_test_scheduler()

        # Init course
        make_test_course()

        deadline_manager.check_course_assignment_notifications(2, sched)

        send_warnings.assert_called_with([(
            '4',
            'The deadline for Learning booleans is in 0 hours and 17 minutes.')
                                          ])

        assignments_sent = AssignmentNotificationSent.objects.all()
        self.assertEqual(len(assignments_sent), 2)
        self.assertEqual(assignments_sent[0].name, '6early')
        self.assertEqual(assignments_sent[1].name, '9early')

        assignments_to_check_on_update = deadline_manager.get_assignments(2)
        update.assert_called_with(2, sched, assignments_to_check_on_update)

        # Trigger twice but only send notification once
        deadline_manager.check_course_assignment_notifications(2, sched)

        send_warnings.assert_called_once()

        assignments_sent = AssignmentNotificationSent.objects.all()
        self.assertEqual(len(assignments_sent), 2)
        self.assertEqual(assignments_sent[0].name, '6early')
        self.assertEqual(assignments_sent[1].name, '9early')

        update.assert_called_with(2, sched, assignments_to_check_on_update)
        self.assertEqual(len(update.mock_calls), 2)
    def test_update_first_assignment_notification_time_of_course_late(
            self, time, reschedule, get_assignments, check_if_ended):
        sched = get_test_scheduler()
        dt_of_deadline = datetime.fromtimestamp(1573776060)
        dt_of_early = datetime.fromtimestamp(1573776060 - 86400)

        # Test without course
        deadline_manager.update_first_assignment_notification_time_of_course(
            2, sched)
        # Assert
        reschedule.assert_not_called()
        self.assertEqual(len(FirstAssignmentOfCourse.objects.all()), 0)

        # Test with course
        make_test_course()
        # Run
        deadline_manager.update_first_assignment_notification_time_of_course(
            2, sched)
        # Assert
        reschedule.assert_called_with('2assignment_check', 'date',
                                      {'run_date': dt_of_early}, dt_of_early)
        reschedule.assert_called_once()
        self.assertEqual(len(FirstAssignmentOfCourse.objects.all()), 1)
        self.assertEqual(
            FirstAssignmentOfCourse.objects.get(course_id=2).time, dt_of_early)

        # Test with filled in assignments_to_check
        # Clear previous result
        FirstAssignmentOfCourse.objects.get(course_id=2).delete()
        # Run
        deadline_manager.update_first_assignment_notification_time_of_course(
            2, sched, deadline_manager.get_assignments(2))
        # Assert
        reschedule.assert_called_with('2assignment_check', 'date',
                                      {'run_date': dt_of_early}, dt_of_early)
        self.assertEqual(len(FirstAssignmentOfCourse.objects.all()), 1)
        self.assertEqual(
            FirstAssignmentOfCourse.objects.get(course_id=2).time, dt_of_early)

        # Test with early notification already sent
        assignments_sent = AssignmentNotificationSent('6early', 6, 'early',
                                                      datetime.today())
        assignments_sent.save()
        assignments_sent = AssignmentNotificationSent('9early', 9, 'early',
                                                      datetime.today())
        assignments_sent.save()
        # Clear previous result
        FirstAssignmentOfCourse.objects.get(course_id=2).delete()
        # Run
        deadline_manager.update_first_assignment_notification_time_of_course(
            2, sched)
        # Assert
        reschedule.assert_called_with('2assignment_check', 'date',
                                      {'run_date': dt_of_deadline},
                                      dt_of_deadline)
        self.assertEqual(len(FirstAssignmentOfCourse.objects.all()), 1)
        self.assertEqual(
            FirstAssignmentOfCourse.objects.get(course_id=2).time,
            dt_of_deadline)

        # Test with filled in assignments_to_check
        # Clear previous result
        FirstAssignmentOfCourse.objects.get(course_id=2).delete()
        # Run
        deadline_manager.update_first_assignment_notification_time_of_course(
            2, sched, deadline_manager.get_assignments(2))
        # Assert
        reschedule.assert_called_with('2assignment_check', 'date',
                                      {'run_date': dt_of_deadline},
                                      dt_of_deadline)
        self.assertEqual(len(FirstAssignmentOfCourse.objects.all()), 1)
        self.assertEqual(
            FirstAssignmentOfCourse.objects.get(course_id=2).time,
            dt_of_deadline)

        # Test with FirstAssignmentOfCourse.time not being empty
        AssignmentNotificationSent.objects.get(name='6early').delete()
        AssignmentNotificationSent.objects.get(name='9early').delete()
        # Run
        deadline_manager.update_first_assignment_notification_time_of_course(
            2, sched)
        # Assert
        reschedule.assert_called_with('2assignment_check', 'date',
                                      {'run_date': dt_of_early}, dt_of_early)
        self.assertEqual(len(FirstAssignmentOfCourse.objects.all()), 1)
        self.assertEqual(
            FirstAssignmentOfCourse.objects.get(course_id=2).time, dt_of_early)

        # Test with no unsent assignments left
        assignments_sent = AssignmentNotificationSent('6early', 6, 'early',
                                                      datetime.today())
        assignments_sent.save()
        assignments_sent = AssignmentNotificationSent('6late', 6, 'late',
                                                      datetime.today())
        assignments_sent.save()
        assignments_sent = AssignmentNotificationSent('9early', 9, 'early',
                                                      datetime.today())
        assignments_sent.save()
        assignments_sent = AssignmentNotificationSent('9late', 9, 'late',
                                                      datetime.today())
        assignments_sent.save()
        reschedule.reset_mock()
        FirstAssignmentOfCourse.objects.get(course_id=2).delete()
        # Run
        deadline_manager.update_first_assignment_notification_time_of_course(
            2, sched)
        # Assert
        reschedule.assert_not_called()
        self.assertEqual(len(FirstAssignmentOfCourse.objects.all()), 1)
    def test_check_course_assignment_notifications_not_yet(
            self, time, send_warnings, get_assignments, status, enrolled_users,
            update, check_if_ended):
        """Test notification which should send in the future"""
        # Init scheduler
        sched = get_test_scheduler()

        # Init course
        make_test_course()

        deadline_manager.check_course_assignment_notifications(2, sched)
        send_warnings.assert_not_called()
        assignments_to_check_on_update = deadline_manager.get_assignments(2)
        update.assert_called_with(2, sched, assignments_to_check_on_update)

        # Test when already sent as early
        assignments_sent = AssignmentNotificationSent('6early', 6, 'early',
                                                      datetime.today())
        assignments_sent.save()
        assignments_sent = AssignmentNotificationSent('9early', 9, 'early',
                                                      datetime.today())
        assignments_sent.save()

        deadline_manager.check_course_assignment_notifications(2, sched)
        send_warnings.assert_not_called()
        update.assert_called_with(2, sched, assignments_to_check_on_update)

        # Test when already sent as late
        assignments_sent = AssignmentNotificationSent('6late', 6, 'late',
                                                      datetime.today())
        assignments_sent.save()
        assignments_sent = AssignmentNotificationSent('9late', 9, 'late',
                                                      datetime.today())
        assignments_sent.save()

        deadline_manager.check_course_assignment_notifications(2, sched)
        send_warnings.assert_not_called()
        assignments_to_check_on_update = []
        update.assert_called_with(2, sched, assignments_to_check_on_update)

        @patch(
            'scheduler.deadline_manager.update_first_assignment_notification_time_of_course'
        )
        @patch('scheduler.deadline_manager.send_single_assignment_notification'
               )
        @patch('assistants.moodle.get_course_by_id_field',
               return_value=test_data.test_get_courses_by_id_ended)
        @patch('assistants.moodle.get_assignments',
               return_value=test_data.test_get_assignments_data)
        @patch('time.time', return_value=1800000000)
        def test_check_course_assignment_notifications_course_ended(
                self, time, get_assignments, check_if_ended, send_single,
                update_first):
            sched = get_test_scheduler()
            make_test_course()

            # Add deadline notification job
            sched.add_deadline_notification(2)
            # Force job because scheduler is paused while testing
            deadline_manager.check_course_assignment_notifications(2, sched)

            # Assert that nothing was called because the course has already ended
            send_single.assert_not_called()
            update_first.assert_not_called()

            # Assert that the job has been removed
            self.assertNotIn('2assignment_check', sched.jobs)
            self.assertEqual(list(CronJob.objects.filter(course=2)), [])
            self.assertEqual(len(FirstAssignmentOfCourse.objects.all()), 0)