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)
    def test_check_course_assignment_notifications_none(
            self, time, send_warnings, get_assignments, status, enrolled_users,
            update, check_if_ended):
        """Test no notification check"""
        # Init scheduler
        sched = get_test_scheduler()

        # Test without 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('9early', 9, 'early',
                                                      datetime.today())
        assignments_sent.save()
        assignments_sent = AssignmentNotificationSent('9late', 9, 'late',
                                                      datetime.today())
        assignments_sent.save()
        assignments_sent = AssignmentNotificationSent('6early', 6, 'early',
                                                      datetime.today())
        assignments_sent.save()
        assignments_sent = AssignmentNotificationSent('6late', 6, '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)
        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_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)