コード例 #1
0
    def test_date_with_existing_schedule(self):
        """ If a schedule is created while deadlines are disabled, they shouldn't magically appear once the feature is
        turned on. """
        course = create_self_paced_course_run(days_till_start=-1)
        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=False)
        course_config = CourseDynamicUpgradeDeadlineConfiguration.objects.create(
            enabled=False, course_id=course.id)
        ScheduleConfigFactory.create(site=self.site,
                                     enabled=True,
                                     create_schedules=True)
        enrollment = CourseEnrollmentFactory(course_id=course.id,
                                             mode=CourseMode.AUDIT)

        # The enrollment has a schedule, but the upgrade deadline should be None
        self.assertIsNone(enrollment.schedule.upgrade_deadline)

        block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
        expected = CourseMode.objects.get(
            course_id=course.id,
            mode_slug=CourseMode.VERIFIED).expiration_datetime
        self.assertEqual(block.date, expected)

        # Now if we turn on the feature for this course, this existing enrollment should be unaffected
        course_config.enabled = True
        course_config.save()

        block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
        self.assertEqual(block.date, expected)
コード例 #2
0
    def handle(self, *args, **options):
        courses = modulestore().get_courses()

        # Find the largest auto-generated course, and pick the next sequence id to generate the next
        # course with.
        max_org_sequence_id = max(
            int(course.org[4:]) for course in courses
            if course.org.startswith('org.'))

        XMODULE_FACTORY_LOCK.enable()
        CourseFactory.reset_sequence(max_org_sequence_id + 1, force=True)
        course = CourseFactory.create(
            start=datetime.datetime.today() - datetime.timedelta(days=30),
            end=datetime.datetime.today() + datetime.timedelta(days=30),
            number=factory.Sequence('schedules_test_course_{}'.format),
            display_name=factory.Sequence('Schedules Test Course {}'.format),
        )
        XMODULE_FACTORY_LOCK.disable()
        course_overview = CourseOverview.load_from_module_store(course.id)
        ThreeDayNudgeSchedule.create(enrollment__course=course_overview)
        TenDayNudgeSchedule.create(enrollment__course=course_overview)
        UpgradeReminderSchedule.create(enrollment__course=course_overview)
        ContentHighlightSchedule.create(enrollment__course=course_overview)

        ScheduleConfigFactory.create(site=Site.objects.get(name='example.com'))
コード例 #3
0
    def test_date_with_self_paced_with_enrollment_after_course_start(self):
        """ Enrolling after a course begins should result in the upgrade deadline being set relative to the
        enrollment date.

        Additionally, OrgDynamicUpgradeDeadlineConfiguration should override the number of days until the deadline,
        and CourseDynamicUpgradeDeadlineConfiguration should override the org-level override.
        """
        global_config = DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
        course = create_self_paced_course_run(days_till_start=-1, org_id='TestOrg')
        ScheduleConfigFactory.create(site=self.site, enabled=True, create_schedules=True)
        enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
        block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
        expected = enrollment.created + timedelta(days=global_config.deadline_days)
        self.assertEqual(block.date, expected)

        # Orgs should be able to override the deadline
        org_config = OrgDynamicUpgradeDeadlineConfiguration.objects.create(
            enabled=True, org_id=course.org, deadline_days=4
        )
        enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
        block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
        expected = enrollment.created + timedelta(days=org_config.deadline_days)
        self.assertEqual(block.date, expected)

        # Courses should be able to override the deadline (and the org-level override)
        course_config = CourseDynamicUpgradeDeadlineConfiguration.objects.create(
            enabled=True, course_id=course.id, deadline_days=3
        )
        enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
        block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
        expected = enrollment.created + timedelta(days=course_config.deadline_days)
        self.assertEqual(block.date, expected)
コード例 #4
0
    def test_site_config(self, this_org_list, other_org_list, expected_message_count, mock_ace):
        filtered_org = 'filtered_org'
        unfiltered_org = 'unfiltered_org'
        this_config = SiteConfigurationFactory.create(values={'course_org_filter': this_org_list})
        other_config = SiteConfigurationFactory.create(values={'course_org_filter': other_org_list})

        for config in (this_config, other_config):
            ScheduleConfigFactory.create(site=config.site)

        user1 = UserFactory.create(id=self.task.num_bins)
        user2 = UserFactory.create(id=self.task.num_bins * 2)
        current_day, offset, target_day, upgrade_deadline = self._get_dates()

        self._schedule_factory(
            enrollment__course__org=filtered_org,
            enrollment__user=user1,
        )
        self._schedule_factory(
            enrollment__course__org=unfiltered_org,
            enrollment__user=user1,
        )
        self._schedule_factory(
            enrollment__course__org=unfiltered_org,
            enrollment__user=user2,
        )

        with patch.object(self.task, 'async_send_task') as mock_schedule_send:
            self.task().apply(kwargs=dict(
                site_id=this_config.site.id, target_day_str=serialize(target_day), day_offset=offset, bin_num=0
            ))

        self.assertEqual(mock_schedule_send.apply_async.call_count, expected_message_count)
        self.assertFalse(mock_ace.send.called)
コード例 #5
0
    def setUp(self):
        super(VerifiedUpgradeToolTest, self).setUp()

        self.course_verified_mode = CourseModeFactory(
            course_id=self.course.id,
            mode_slug=CourseMode.VERIFIED,
            expiration_datetime=self.now + datetime.timedelta(days=30),
        )

        patcher = patch('openedx.core.djangoapps.schedules.signals.get_current_site')
        mock_get_current_site = patcher.start()
        self.addCleanup(patcher.stop)
        mock_get_current_site.return_value = SiteFactory.create()

        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)

        ScheduleConfigFactory.create(
            site=mock_get_current_site.return_value,
            create_schedules=True
        )

        self.enrollment = CourseEnrollmentFactory(
            course_id=self.course.id,
            mode=CourseMode.AUDIT,
            course=self.course_overview,
        )
        self.request = RequestFactory().request()
        self.request.user = self.enrollment.user
        crum.set_current_request(self.request)
コード例 #6
0
    def handle(self, *args, **options):
        courses = modulestore().get_courses()

        # Find the largest auto-generated course, and pick the next sequence id to generate the next
        # course with.
        max_org_sequence_id = max([0] + [
            int(course.org[4:])
            for course in courses if course.org.startswith('org.')
        ])

        XMODULE_FACTORY_LOCK.enable()
        CourseFactory.reset_sequence(max_org_sequence_id + 1, force=True)
        course = CourseFactory.create(
            start=datetime.datetime.today() - datetime.timedelta(days=30),
            end=datetime.datetime.today() + datetime.timedelta(days=30),
            number=factory.Sequence('schedules_test_course_{}'.format),
            display_name=factory.Sequence(u'Schedules Test Course {}'.format),
        )
        XMODULE_FACTORY_LOCK.disable()
        course_overview = CourseOverview.load_from_module_store(course.id)
        CourseModeFactory.create(course_id=course_overview.id,
                                 mode_slug=CourseMode.AUDIT)
        CourseModeFactory.create(course_id=course_overview.id,
                                 mode_slug=CourseMode.VERIFIED)
        CourseDurationLimitExpirySchedule.create_batch(
            20, enrollment__course=course_overview)

        ScheduleConfigFactory.create(site=Site.objects.get(name='example.com'))
コード例 #7
0
    def test_site_config(self, org_list, exclude_orgs, expected_message_count, mock_schedule_send, mock_ace):
        filtered_org = 'filtered_org'
        unfiltered_org = 'unfiltered_org'
        site1 = SiteFactory.create(domain='foo1.bar', name='foo1.bar')
        limited_config = SiteConfigurationFactory.create(values={'course_org_filter': [filtered_org]}, site=site1)
        site2 = SiteFactory.create(domain='foo2.bar', name='foo2.bar')
        unlimited_config = SiteConfigurationFactory.create(values={'course_org_filter': []}, site=site2)

        for config in (limited_config, unlimited_config):
            ScheduleConfigFactory.create(site=config.site)

        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 2, 17, 44, 30, tzinfo=pytz.UTC),
            enrollment__course__org=filtered_org,
        )
        for _ in range(2):
            ScheduleFactory.create(
                start=datetime.datetime(2017, 8, 2, 17, 44, 30, tzinfo=pytz.UTC),
                enrollment__course__org=unfiltered_org,
            )

        test_time_str = serialize(datetime.datetime(2017, 8, 2, 17, tzinfo=pytz.UTC))
        with self.assertNumQueries(2):
            tasks.recurring_nudge_schedule_hour(
                limited_config.site.id, 3, test_time_str, org_list=org_list, exclude_orgs=exclude_orgs,
            )

        self.assertEqual(mock_schedule_send.apply_async.call_count, expected_message_count)
        self.assertFalse(mock_ace.send.called)
コード例 #8
0
    def setUp(self):
        super(VerifiedUpgradeToolTest, self).setUp()

        self.course_verified_mode = CourseModeFactory(
            course_id=self.course.id,
            mode_slug=CourseMode.VERIFIED,
            expiration_datetime=self.now + datetime.timedelta(days=30),
        )

        patcher = patch(
            'openedx.core.djangoapps.schedules.signals.get_current_site')
        mock_get_current_site = patcher.start()
        self.addCleanup(patcher.stop)
        mock_get_current_site.return_value = SiteFactory.create()

        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)

        ScheduleConfigFactory.create(site=mock_get_current_site.return_value,
                                     create_schedules=True)

        self.enrollment = CourseEnrollmentFactory(
            course_id=self.course.id,
            mode=CourseMode.AUDIT,
            course=self.course_overview,
        )
        self.request = RequestFactory().request()
        self.request.user = self.enrollment.user
        crum.set_current_request(self.request)
コード例 #9
0
    def test_delivery_disabled(self, mock_ace):
        ScheduleConfigFactory.create(site=self.site_config.site,
                                     deliver_recurring_nudge=False)

        mock_msg = Mock()
        tasks._recurring_nudge_schedule_send(self.site_config.site.id,
                                             mock_msg)
        self.assertFalse(mock_ace.send.called)
コード例 #10
0
    def setUp(self):
        super(ScheduleSendEmailTestBase, self).setUp()

        site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory.create(site=site)
        ScheduleConfigFactory.create(site=self.site_config.site)

        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
コード例 #11
0
    def test_enqueue_disabled(self, mock_schedule_bin, mock_ace):
        ScheduleConfigFactory.create(site=self.site_config.site, enqueue_recurring_nudge=False)

        current_time = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC)
        nudge.ScheduleStartResolver(self.site_config.site, current_time).send(3)
        self.assertFalse(mock_schedule_bin.called)
        self.assertFalse(mock_schedule_bin.apply_async.called)
        self.assertFalse(mock_ace.send.called)
コード例 #12
0
    def setUp(self):
        ScheduleFactory.create(start=datetime.datetime(2017, 8, 1, 15, 44, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(start=datetime.datetime(2017, 8, 1, 17, 34, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(start=datetime.datetime(2017, 8, 2, 15, 34, 30, tzinfo=pytz.UTC))

        site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory.create(site=site)
        ScheduleConfigFactory.create(site=self.site_config.site)
コード例 #13
0
 def _update_schedule_config(self, schedule_config_kwargs):
     """
     Updates the schedule config model by making sure the new entry
     has a later timestamp.
     """
     later_time = datetime.datetime.now(pytz.UTC) + datetime.timedelta(minutes=1)
     with freeze_time(later_time):
         ScheduleConfigFactory.create(**schedule_config_kwargs)
コード例 #14
0
 def _update_schedule_config(self, schedule_config_kwargs):
     """
     Updates the schedule config model by making sure the new entry
     has a later timestamp.
     """
     later_time = datetime.datetime.now(pytz.UTC) + datetime.timedelta(minutes=1)
     with freeze_time(later_time):
         ScheduleConfigFactory.create(**schedule_config_kwargs)
コード例 #15
0
    def test_enqueue_disabled(self, mock_schedule_bin, mock_ace):
        ScheduleConfigFactory.create(site=self.site_config.site, enqueue_recurring_nudge=False)

        current_datetime = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC)
        nudge.ScheduleStartResolver(self.site_config.site, current_datetime).send(3)
        self.assertFalse(mock_schedule_bin.called)
        self.assertFalse(mock_schedule_bin.apply_async.called)
        self.assertFalse(mock_ace.send.called)
コード例 #16
0
    def test_enqueue_disabled(self, mock_schedule_bin, mock_ace):
        ScheduleConfigFactory.create(site=self.site_config.site, enqueue_upgrade_reminder=False)

        current_day = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC)
        reminder.UpgradeReminderResolver(self.site_config.site, current_day).send(3)
        self.assertFalse(mock_schedule_bin.called)
        self.assertFalse(mock_schedule_bin.apply_async.called)
        self.assertFalse(mock_ace.send.called)
コード例 #17
0
    def test_site_config(self, org_list, exclude_orgs, expected_message_count,
                         mock_schedule_send, mock_ace):
        filtered_org = 'filtered_org'
        unfiltered_org = 'unfiltered_org'
        site1 = SiteFactory.create(domain='foo1.bar', name='foo1.bar')
        limited_config = SiteConfigurationFactory.create(
            values={'course_org_filter': [filtered_org]}, site=site1)
        site2 = SiteFactory.create(domain='foo2.bar', name='foo2.bar')
        unlimited_config = SiteConfigurationFactory.create(
            values={'course_org_filter': []}, site=site2)

        for config in (limited_config, unlimited_config):
            ScheduleConfigFactory.create(site=config.site)

        filtered_sched = ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 2, 17, 44, 30, tzinfo=pytz.UTC),
            enrollment__course__org=filtered_org,
        )
        unfiltered_scheds = [
            ScheduleFactory.create(
                start=datetime.datetime(2017,
                                        8,
                                        2,
                                        17,
                                        44,
                                        30,
                                        tzinfo=pytz.UTC),
                enrollment__course__org=unfiltered_org,
            ) for _ in range(2)
        ]

        print(filtered_sched.enrollment)
        print(filtered_sched.enrollment.course)
        print(filtered_sched.enrollment.course.org)
        print(unfiltered_scheds[0].enrollment)
        print(unfiltered_scheds[0].enrollment.course)
        print(unfiltered_scheds[0].enrollment.course.org)
        print(unfiltered_scheds[1].enrollment)
        print(unfiltered_scheds[1].enrollment.course)
        print(unfiltered_scheds[1].enrollment.course.org)

        test_time_str = serialize(
            datetime.datetime(2017, 8, 2, 17, tzinfo=pytz.UTC))
        with self.assertNumQueries(1):
            tasks.recurring_nudge_schedule_hour(
                limited_config.site.id,
                3,
                test_time_str,
                org_list=org_list,
                exclude_orgs=exclude_orgs,
            )

        print(mock_schedule_send.mock_calls)
        self.assertEqual(mock_schedule_send.apply_async.call_count,
                         expected_message_count)
        self.assertFalse(mock_ace.send.called)
コード例 #18
0
    def setUp(self):
        super(TestSendRecurringNudge, self).setUp()

        ScheduleFactory.create(start=datetime.datetime(2017, 8, 1, 15, 44, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(start=datetime.datetime(2017, 8, 1, 17, 34, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(start=datetime.datetime(2017, 8, 2, 15, 34, 30, tzinfo=pytz.UTC))

        site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory.create(site=site)
        ScheduleConfigFactory.create(site=self.site_config.site)
コード例 #19
0
    def setUp(self):
        super(TestSendRecurringNudge, self).setUp()

        ScheduleFactory.create(start=datetime.datetime(2017, 8, 1, 15, 44, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(start=datetime.datetime(2017, 8, 1, 17, 34, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(start=datetime.datetime(2017, 8, 2, 15, 34, 30, tzinfo=pytz.UTC))

        site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory.create(site=site)
        ScheduleConfigFactory.create(site=self.site_config.site)
コード例 #20
0
    def test_enqueue_disabled(self, mock_schedule_bin, mock_ace):
        ScheduleConfigFactory.create(site=self.site_config.site,
                                     enqueue_upgrade_reminder=False)

        current_time = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC)
        reminder.UpgradeReminderResolver(self.site_config.site,
                                         current_time).send(3)
        self.assertFalse(mock_schedule_bin.called)
        self.assertFalse(mock_schedule_bin.apply_async.called)
        self.assertFalse(mock_ace.send.called)
コード例 #21
0
    def setUp(self):
        super(ScheduleSendEmailTestMixin, self).setUp()

        site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory.create(site=site)
        ScheduleConfigFactory.create(site=self.site_config.site)

        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
        CommerceConfiguration.objects.create(checkout_on_ecommerce_service=True)

        self._courses_with_verified_modes = set()
コード例 #22
0
    def setUp(self):
        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 1, 15, 44, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 1, 17, 34, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 2, 15, 34, 30, tzinfo=pytz.UTC))

        site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory.create(site=site)
        ScheduleConfigFactory.create(site=self.site_config.site)
コード例 #23
0
    def setUp(self):
        super(ScheduleSendEmailTestMixin, self).setUp()

        site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory.create(site=site)
        ScheduleConfigFactory.create(site=self.site_config.site)

        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
        CommerceConfiguration.objects.create(checkout_on_ecommerce_service=True)

        self._courses_with_verified_modes = set()
コード例 #24
0
 def test_date_with_self_paced_with_enrollment_before_course_start(self):
     """ Enrolling before a course begins should result in the upgrade deadline being set relative to the
     course start date. """
     global_config = DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
     course = create_self_paced_course_run(days_till_start=3)
     overview = CourseOverview.get_from_id(course.id)
     expected = overview.start + timedelta(days=global_config.deadline_days)
     ScheduleConfigFactory.create(site=self.site, enabled=True, create_schedules=True)
     enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
     block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
     self.assertEqual(block.date, expected)
     self._check_text(block)
コード例 #25
0
    def setUp(self):
        super(TestSendRecurringNudge, self).setUp()

        ScheduleFactory.create(start=datetime.datetime(2017, 8, 1, 15, 44, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(start=datetime.datetime(2017, 8, 1, 17, 34, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(start=datetime.datetime(2017, 8, 2, 15, 34, 30, tzinfo=pytz.UTC))

        site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory.create(site=site)
        ScheduleConfigFactory.create(site=self.site_config.site)

        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
コード例 #26
0
    def setUp(self):
        super(TestSendRecurringNudge, self).setUp()

        ScheduleFactory.create(start=datetime.datetime(2017, 8, 1, 15, 44, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(start=datetime.datetime(2017, 8, 1, 17, 34, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(start=datetime.datetime(2017, 8, 2, 15, 34, 30, tzinfo=pytz.UTC))

        site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory.create(site=site)
        ScheduleConfigFactory.create(site=self.site_config.site)

        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
コード例 #27
0
    def test_deliver_config(self, is_enabled, mock_message, mock_ace):
        schedule_config_kwargs = {
            'site': self.site_config.site,
            self.deliver_config: is_enabled,
        }
        ScheduleConfigFactory.create(**schedule_config_kwargs)

        mock_msg = Mock()
        self.deliver_task(self.site_config.site.id, mock_msg)
        if is_enabled:
            self.assertTrue(mock_ace.send.called)
        else:
            self.assertFalse(mock_ace.send.called)
コード例 #28
0
    def setUp(self):
        super(TestUpgradeReminder, self).setUp()

        ScheduleFactory.create(upgrade_deadline=datetime.datetime(
            2017, 8, 1, 15, 44, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(upgrade_deadline=datetime.datetime(
            2017, 8, 1, 17, 34, 30, tzinfo=pytz.UTC))
        ScheduleFactory.create(upgrade_deadline=datetime.datetime(
            2017, 8, 2, 15, 34, 30, tzinfo=pytz.UTC))

        site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory.create(site=site)
        ScheduleConfigFactory.create(site=self.site_config.site)
コード例 #29
0
    def test_site_config(self, this_org_list, other_org_list,
                         expected_message_count, mock_ace):
        filtered_org = 'filtered_org'
        unfiltered_org = 'unfiltered_org'
        this_config = SiteConfigurationFactory.create(
            values={'course_org_filter': this_org_list})
        other_config = SiteConfigurationFactory.create(
            values={'course_org_filter': other_org_list})

        for config in (this_config, other_config):
            ScheduleConfigFactory.create(site=config.site)

        user1 = UserFactory.create(id=self.tested_task.num_bins)
        user2 = UserFactory.create(id=self.tested_task.num_bins * 2)
        current_day, offset, target_day = self._get_dates()

        ScheduleFactory.create(
            upgrade_deadline=target_day,
            start=target_day,
            enrollment__course__org=filtered_org,
            enrollment__course__self_paced=True,
            enrollment__user=user1,
        )
        ScheduleFactory.create(
            upgrade_deadline=target_day,
            start=target_day,
            enrollment__course__org=unfiltered_org,
            enrollment__course__self_paced=True,
            enrollment__user=user1,
        )
        ScheduleFactory.create(
            upgrade_deadline=target_day,
            start=target_day,
            enrollment__course__org=unfiltered_org,
            enrollment__course__self_paced=True,
            enrollment__user=user2,
        )

        with patch.object(self.tested_task,
                          'async_send_task') as mock_schedule_send:
            self.tested_task.apply(
                kwargs=dict(site_id=this_config.site.id,
                            target_day_str=serialize(target_day),
                            day_offset=offset,
                            bin_num=0))

        self.assertEqual(mock_schedule_send.apply_async.call_count,
                         expected_message_count)
        self.assertFalse(mock_ace.send.called)
コード例 #30
0
    def test_enqueue_config(self, is_enabled):
        schedule_config_kwargs = {
            'site': self.site_config.site,
            self.enqueue_config: is_enabled,
        }
        ScheduleConfigFactory.create(**schedule_config_kwargs)

        current_datetime = datetime.datetime(2017, 8, 1, tzinfo=pytz.UTC)
        with patch.object(self.task, 'apply_async') as mock_apply_async:
            self.task.enqueue(self.site_config.site, current_datetime, 3)

        if is_enabled:
            self.assertTrue(mock_apply_async.called)
        else:
            self.assertFalse(mock_apply_async.called)
コード例 #31
0
    def test_deliver_config(self, is_enabled, mock_message, mock_ace):
        user = UserFactory.create()
        schedule_config_kwargs = {
            'site': self.site_config.site,
            self.deliver_config: is_enabled,
        }
        mock_message.from_string.return_value.recipient.username = user.username
        ScheduleConfigFactory.create(**schedule_config_kwargs)

        mock_msg = Mock()
        self.deliver_task(self.site_config.site.id, mock_msg)
        if is_enabled:
            self.assertTrue(mock_ace.send.called)
        else:
            self.assertFalse(mock_ace.send.called)
コード例 #32
0
 def test_date_with_self_paced_with_enrollment_before_course_start(self):
     """ Enrolling before a course begins should result in the upgrade deadline being set relative to the
     course start date. """
     global_config = DynamicUpgradeDeadlineConfiguration.objects.create(
         enabled=True)
     course = create_self_paced_course_run(days_till_start=3)
     overview = CourseOverview.get_from_id(course.id)
     expected = overview.start + timedelta(days=global_config.deadline_days)
     ScheduleConfigFactory.create(site=self.site,
                                  enabled=True,
                                  create_schedules=True)
     enrollment = CourseEnrollmentFactory(course_id=course.id,
                                          mode=CourseMode.AUDIT)
     block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
     self.assertEqual(block.date, expected)
     self._check_text(block)
コード例 #33
0
    def test_site_config(self, org_list, exclude_orgs, expected_message_count,
                         mock_schedule_send, mock_ace):
        filtered_org = 'filtered_org'
        unfiltered_org = 'unfiltered_org'
        site1 = SiteFactory.create(domain='foo1.bar', name='foo1.bar')
        limited_config = SiteConfigurationFactory.create(
            values={'course_org_filter': [filtered_org]}, site=site1)
        site2 = SiteFactory.create(domain='foo2.bar', name='foo2.bar')
        unlimited_config = SiteConfigurationFactory.create(
            values={'course_org_filter': []}, site=site2)

        for config in (limited_config, unlimited_config):
            ScheduleConfigFactory.create(site=config.site)

        user1 = UserFactory.create()
        user2 = UserFactory.create()

        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 2, 17, 44, 30, tzinfo=pytz.UTC),
            enrollment__course__org=filtered_org,
            enrollment__user=user1,
        )
        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 2, 17, 44, 30, tzinfo=pytz.UTC),
            enrollment__course__org=unfiltered_org,
            enrollment__user=user1,
        )
        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 2, 17, 44, 30, tzinfo=pytz.UTC),
            enrollment__course__org=unfiltered_org,
            enrollment__user=user2,
        )

        test_time_str = serialize(
            datetime.datetime(2017, 8, 2, 17, tzinfo=pytz.UTC))
        with self.assertNumQueries(2):
            tasks.recurring_nudge_schedule_hour(
                limited_config.site.id,
                day=3,
                target_hour_str=test_time_str,
                org_list=org_list,
                exclude_orgs=exclude_orgs,
            )

        self.assertEqual(mock_schedule_send.apply_async.call_count,
                         expected_message_count)
        self.assertFalse(mock_ace.send.called)
コード例 #34
0
    def test_date_with_self_paced_with_enrollment_after_course_start(self):
        """ Enrolling after a course begins should result in the upgrade deadline being set relative to the
        enrollment date.

        Additionally, OrgDynamicUpgradeDeadlineConfiguration should override the number of days until the deadline,
        and CourseDynamicUpgradeDeadlineConfiguration should override the org-level override.
        """
        global_config = DynamicUpgradeDeadlineConfiguration.objects.create(
            enabled=True)
        course = create_self_paced_course_run(days_till_start=-1,
                                              org_id='TestOrg')
        ScheduleConfigFactory.create(site=self.site,
                                     enabled=True,
                                     create_schedules=True)
        enrollment = CourseEnrollmentFactory(course_id=course.id,
                                             mode=CourseMode.AUDIT)
        block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
        expected = enrollment.created + timedelta(
            days=global_config.deadline_days)
        self.assertEqual(block.date, expected)

        # Orgs should be able to override the deadline
        org_config = OrgDynamicUpgradeDeadlineConfiguration.objects.create(
            enabled=True, org_id=course.org, deadline_days=4)
        enrollment = CourseEnrollmentFactory(course_id=course.id,
                                             mode=CourseMode.AUDIT)
        block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
        expected = enrollment.created + timedelta(
            days=org_config.deadline_days)
        self.assertEqual(block.date, expected)

        # Courses should be able to override the deadline (and the org-level override)
        course_config = CourseDynamicUpgradeDeadlineConfiguration.objects.create(
            enabled=True, course_id=course.id, deadline_days=3)
        enrollment = CourseEnrollmentFactory(course_id=course.id,
                                             mode=CourseMode.AUDIT)
        block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
        expected = enrollment.created + timedelta(
            days=course_config.deadline_days)
        self.assertEqual(block.date, expected)
コード例 #35
0
    def test_site_config(self, org_list, exclude_orgs, expected_message_count, mock_schedule_send, mock_ace):
        filtered_org = 'filtered_org'
        unfiltered_org = 'unfiltered_org'
        site1 = SiteFactory.create(domain='foo1.bar', name='foo1.bar')
        limited_config = SiteConfigurationFactory.create(values={'course_org_filter': [filtered_org]}, site=site1)
        site2 = SiteFactory.create(domain='foo2.bar', name='foo2.bar')
        unlimited_config = SiteConfigurationFactory.create(values={'course_org_filter': []}, site=site2)

        for config in (limited_config, unlimited_config):
            ScheduleConfigFactory.create(site=config.site)

        user1 = UserFactory.create(id=tasks.RECURRING_NUDGE_NUM_BINS)
        user2 = UserFactory.create(id=tasks.RECURRING_NUDGE_NUM_BINS * 2)

        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 3, 17, 44, 30, tzinfo=pytz.UTC),
            enrollment__course__org=filtered_org,
            enrollment__user=user1,
        )
        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 3, 17, 44, 30, tzinfo=pytz.UTC),
            enrollment__course__org=unfiltered_org,
            enrollment__user=user1,
        )
        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 3, 17, 44, 30, tzinfo=pytz.UTC),
            enrollment__course__org=unfiltered_org,
            enrollment__user=user2,
        )

        test_time = datetime.datetime(2017, 8, 3, 17, tzinfo=pytz.UTC)
        test_time_str = serialize(test_time)
        with self.assertNumQueries(NUM_QUERIES_WITH_MATCHES, table_blacklist=WAFFLE_TABLES):
            tasks.recurring_nudge_schedule_bin(
                limited_config.site.id, target_day_str=test_time_str, day_offset=-3, bin_num=0,
                org_list=org_list, exclude_orgs=exclude_orgs,
            )

        self.assertEqual(mock_schedule_send.apply_async.call_count, expected_message_count)
        self.assertFalse(mock_ace.send.called)
コード例 #36
0
    def test_site_config(self, org_list, exclude_orgs, expected_message_count, mock_schedule_send, mock_ace):
        filtered_org = 'filtered_org'
        unfiltered_org = 'unfiltered_org'
        site1 = SiteFactory.create(domain='foo1.bar', name='foo1.bar')
        limited_config = SiteConfigurationFactory.create(values={'course_org_filter': [filtered_org]}, site=site1)
        site2 = SiteFactory.create(domain='foo2.bar', name='foo2.bar')
        unlimited_config = SiteConfigurationFactory.create(values={'course_org_filter': []}, site=site2)

        for config in (limited_config, unlimited_config):
            ScheduleConfigFactory.create(site=config.site)

        user1 = UserFactory.create(id=tasks.RECURRING_NUDGE_NUM_BINS)
        user2 = UserFactory.create(id=tasks.RECURRING_NUDGE_NUM_BINS * 2)

        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 3, 17, 44, 30, tzinfo=pytz.UTC),
            enrollment__course__org=filtered_org,
            enrollment__user=user1,
        )
        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 3, 17, 44, 30, tzinfo=pytz.UTC),
            enrollment__course__org=unfiltered_org,
            enrollment__user=user1,
        )
        ScheduleFactory.create(
            start=datetime.datetime(2017, 8, 3, 17, 44, 30, tzinfo=pytz.UTC),
            enrollment__course__org=unfiltered_org,
            enrollment__user=user2,
        )

        test_datetime = datetime.datetime(2017, 8, 3, 17, tzinfo=pytz.UTC)
        test_datetime_str = serialize(test_datetime)
        with self.assertNumQueries(NUM_QUERIES_WITH_MATCHES, table_blacklist=WAFFLE_TABLES):
            tasks.recurring_nudge_schedule_bin(
                limited_config.site.id, target_day_str=test_datetime_str, day_offset=-3, bin_num=0,
                org_list=org_list, exclude_orgs=exclude_orgs,
            )

        self.assertEqual(mock_schedule_send.apply_async.call_count, expected_message_count)
        self.assertFalse(mock_ace.send.called)
コード例 #37
0
    def setUp(self):
        super(TestBinnedSchedulesBaseResolver, self).setUp()

        self.site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory(site=self.site)
        self.schedule_config = ScheduleConfigFactory.create(site=self.site)
        self.resolver = BinnedSchedulesBaseResolver(
            async_send_task=Mock(name='async_send_task'),
            site=self.site,
            target_datetime=datetime.datetime.now(),
            day_offset=3,
            bin_num=2,
        )
コード例 #38
0
    def test_date_with_existing_schedule(self):
        """ If a schedule is created while deadlines are disabled, they shouldn't magically appear once the feature is
        turned on. """
        course = create_self_paced_course_run(days_till_start=-1)
        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=False)
        course_config = CourseDynamicUpgradeDeadlineConfiguration.objects.create(enabled=False, course_id=course.id)
        ScheduleConfigFactory.create(site=self.site, enabled=True, create_schedules=True)
        enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)

        # The enrollment has a schedule, but the upgrade deadline should be None
        self.assertIsNone(enrollment.schedule.upgrade_deadline)

        block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
        expected = CourseMode.objects.get(course_id=course.id, mode_slug=CourseMode.VERIFIED).expiration_datetime
        self.assertEqual(block.date, expected)

        # Now if we turn on the feature for this course, this existing enrollment should be unaffected
        course_config.enabled = True
        course_config.save()

        block = VerifiedUpgradeDeadlineDate(course, enrollment.user)
        self.assertEqual(block.date, expected)
コード例 #39
0
    def handle(self, *args, **options):
        courses = modulestore().get_courses()

        # Find the largest auto-generated course, and pick the next sequence id to generate the next
        # course with.
        max_org_sequence_id = max([0] + [int(course.org[4:]) for course in courses if course.org.startswith('org.')])

        XMODULE_FACTORY_LOCK.enable()
        CourseFactory.reset_sequence(max_org_sequence_id + 1, force=True)
        course = CourseFactory.create(
            start=datetime.datetime.today() - datetime.timedelta(days=30),
            end=datetime.datetime.today() + datetime.timedelta(days=30),
            number=factory.Sequence('schedules_test_course_{}'.format),
            display_name=factory.Sequence(u'Schedules Test Course {}'.format),
        )
        XMODULE_FACTORY_LOCK.disable()
        course_overview = CourseOverview.load_from_module_store(course.id)
        CourseModeFactory.create(course_id=course_overview.id, mode_slug=CourseMode.AUDIT)
        CourseModeFactory.create(course_id=course_overview.id, mode_slug=CourseMode.VERIFIED)
        CourseDurationLimitExpirySchedule.create_batch(20, enrollment__course=course_overview)

        ScheduleConfigFactory.create(site=Site.objects.get(name='example.com'))
コード例 #40
0
    def setUp(self):
        super(TestBinnedSchedulesBaseResolver, self).setUp()

        self.site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory(site=self.site)
        self.schedule_config = ScheduleConfigFactory.create(site=self.site)
        self.resolver = BinnedSchedulesBaseResolver(
            async_send_task=Mock(name='async_send_task'),
            site=self.site,
            target_datetime=datetime.datetime.now(),
            day_offset=3,
            bin_num=2,
        )
コード例 #41
0
    def handle(self, *args, **options):
        courses = modulestore().get_courses()

        # Find the largest auto-generated course, and pick the next sequence id to generate the next
        # course with.
        max_org_sequence_id = max(int(course.org[4:]) for course in courses if course.org.startswith('org.'))

        XMODULE_FACTORY_LOCK.enable()
        CourseFactory.reset_sequence(max_org_sequence_id + 1, force=True)
        course = CourseFactory.create(
            start=datetime.datetime.today() - datetime.timedelta(days=30),
            end=datetime.datetime.today() + datetime.timedelta(days=30),
            number=factory.Sequence('schedules_test_course_{}'.format),
            display_name=factory.Sequence('Schedules Test Course {}'.format),
        )
        XMODULE_FACTORY_LOCK.disable()
        course_overview = CourseOverview.load_from_module_store(course.id)
        ThreeDayNudgeSchedule.create(enrollment__course=course_overview)
        TenDayNudgeSchedule.create(enrollment__course=course_overview)
        UpgradeReminderSchedule.create(enrollment__course=course_overview)
        ContentHighlightSchedule.create(enrollment__course=course_overview)

        ScheduleConfigFactory.create(site=Site.objects.get(name='example.com'))
コード例 #42
0
    def test_site_config(self, this_org_list, other_org_list,
                         expected_message_count, mock_ace):
        filtered_org = 'filtered_org'
        unfiltered_org = 'unfiltered_org'
        this_config = SiteConfigurationFactory.create(
            site_values={'course_org_filter': this_org_list})
        other_config = SiteConfigurationFactory.create(
            site_values={'course_org_filter': other_org_list})

        for config in (this_config, other_config):
            ScheduleConfigFactory.create(site=config.site)

        user1 = UserFactory.create(id=self._next_user_id())
        user2 = UserFactory.create(id=user1.id + self.task.num_bins)
        current_day, offset, target_day, upgrade_deadline = self._get_dates()  # lint-amnesty, pylint: disable=unused-variable

        self._schedule_factory(
            enrollment__course__org=filtered_org,
            enrollment__user=user1,
        )
        self._schedule_factory(
            enrollment__course__org=unfiltered_org,
            enrollment__user=user1,
        )
        self._schedule_factory(
            enrollment__course__org=unfiltered_org,
            enrollment__user=user2,
        )

        with patch.object(self.task, 'async_send_task') as mock_schedule_send:
            self.task().apply(kwargs=dict(site_id=this_config.site.id,
                                          target_day_str=serialize(target_day),
                                          day_offset=offset,
                                          bin_num=0))

        assert mock_schedule_send.apply_async.call_count == expected_message_count
        assert not mock_ace.send.called
コード例 #43
0
    def test_date_with_org_and_course_config_overrides(
            self, enroll_first, org_config_enabled, org_config_opt_out,
            course_config_enabled, course_config_opt_out,
            expected_dynamic_deadline):
        """ Runs through every combination of org-level plus course-level DynamicUpgradeDeadlineConfiguration enabled
        and opt-out states to verify that course-level overrides the org-level config. """
        course = create_self_paced_course_run(days_till_start=-1,
                                              org_id='TestOrg')
        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
        ScheduleConfigFactory.create(site=self.site,
                                     enabled=True,
                                     create_schedules=True)
        if enroll_first:
            enrollment = CourseEnrollmentFactory(course_id=course.id,
                                                 mode=CourseMode.AUDIT,
                                                 course__self_paced=True)
        OrgDynamicUpgradeDeadlineConfiguration.objects.create(
            enabled=org_config_enabled,
            opt_out=org_config_opt_out,
            org_id=course.id.org)
        CourseDynamicUpgradeDeadlineConfiguration.objects.create(
            enabled=course_config_enabled,
            opt_out=course_config_opt_out,
            course_id=course.id)
        if not enroll_first:
            enrollment = CourseEnrollmentFactory(course_id=course.id,
                                                 mode=CourseMode.AUDIT,
                                                 course__self_paced=True)

        # The enrollment has a schedule, and the upgrade_deadline is set when expected_dynamic_deadline is True
        if not enroll_first:
            self.assertEqual(enrollment.schedule.upgrade_deadline is not None,
                             expected_dynamic_deadline)
        # The CourseEnrollment.upgrade_deadline property method is checking the configs
        self.assertEqual(enrollment.dynamic_upgrade_deadline is not None,
                         expected_dynamic_deadline)
コード例 #44
0
    def test_date_with_org_and_course_config_overrides(self, enroll_first, org_config_enabled, org_config_opt_out,
                                                       course_config_enabled, course_config_opt_out,
                                                       expected_dynamic_deadline):
        """ Runs through every combination of org-level plus course-level DynamicUpgradeDeadlineConfiguration enabled
        and opt-out states to verify that course-level overrides the org-level config. """
        course = create_self_paced_course_run(days_till_start=-1, org_id='TestOrg')
        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
        ScheduleConfigFactory.create(site=self.site, enabled=True, create_schedules=True)
        if enroll_first:
            enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT, course__self_paced=True)
        OrgDynamicUpgradeDeadlineConfiguration.objects.create(
            enabled=org_config_enabled, opt_out=org_config_opt_out, org_id=course.id.org
        )
        CourseDynamicUpgradeDeadlineConfiguration.objects.create(
            enabled=course_config_enabled, opt_out=course_config_opt_out, course_id=course.id
        )
        if not enroll_first:
            enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT, course__self_paced=True)

        # The enrollment has a schedule, and the upgrade_deadline is set when expected_dynamic_deadline is True
        if not enroll_first:
            self.assertEqual(enrollment.schedule.upgrade_deadline is not None, expected_dynamic_deadline)
        # The CourseEnrollment.upgrade_deadline property method is checking the configs
        self.assertEqual(enrollment.dynamic_upgrade_deadline is not None, expected_dynamic_deadline)
コード例 #45
0
    def create_schedule(self, offset=0):  # lint-amnesty, pylint: disable=missing-function-docstring
        self.config = ScheduleConfigFactory()  # lint-amnesty, pylint: disable=attribute-defined-outside-init

        start = datetime.datetime.now(utc) - datetime.timedelta(days=100)
        self.course = CourseFactory.create(start=start, self_paced=True)  # lint-amnesty, pylint: disable=attribute-defined-outside-init

        self.enrollment = CourseEnrollmentFactory(  # lint-amnesty, pylint: disable=attribute-defined-outside-init
            course_id=self.course.id,
            mode=CourseMode.AUDIT,
        )
        self.enrollment.created = start + datetime.timedelta(days=offset)
        self.enrollment.save()

        self.schedule = self.enrollment.schedule  # lint-amnesty, pylint: disable=attribute-defined-outside-init
        self.schedule.start_date = self.enrollment.created
        self.schedule.save()

        self.user = self.enrollment.user  # lint-amnesty, pylint: disable=attribute-defined-outside-init
コード例 #46
0
ファイル: test_utils.py プロジェクト: uetuluk/edx-platform
    def create_schedule(self, enrollment_offset=0, course_start_offset=-100):
        """Makes a course, schedule, and enrollment ready to test"""
        # pylint: disable=attribute-defined-outside-init
        self.config = ScheduleConfigFactory()

        start = datetime.datetime.now(utc) + datetime.timedelta(
            days=course_start_offset)
        self.course = CourseFactory.create(start=start, self_paced=True)

        self.enrollment = CourseEnrollmentFactory(
            course_id=self.course.id,
            mode=CourseMode.AUDIT,
        )
        self.enrollment.created = start + datetime.timedelta(
            days=enrollment_offset)
        self.enrollment.save()

        self.schedule = self.enrollment.schedule
        self.schedule.start_date = self.enrollment.created
        self.schedule.save()

        self.user = self.enrollment.user
コード例 #47
0
ファイル: test_utils.py プロジェクト: sliva/edx-platform
    def create_schedule(self, offset=0):  # lint-amnesty, pylint: disable=missing-function-docstring
        self.config = ScheduleConfigFactory(create_schedules=True)  # lint-amnesty, pylint: disable=attribute-defined-outside-init

        site_patch = patch('openedx.core.djangoapps.schedules.signals.get_current_site', return_value=self.config.site)
        self.addCleanup(site_patch.stop)
        site_patch.start()

        start = datetime.datetime.now(utc) - datetime.timedelta(days=100)
        self.course = CourseFactory.create(start=start, self_paced=True)  # lint-amnesty, pylint: disable=attribute-defined-outside-init

        self.enrollment = CourseEnrollmentFactory(  # lint-amnesty, pylint: disable=attribute-defined-outside-init
            course_id=self.course.id,
            mode=CourseMode.AUDIT,
        )
        self.enrollment.created = start + datetime.timedelta(days=offset)
        self.enrollment.save()

        self.schedule = self.enrollment.schedule  # lint-amnesty, pylint: disable=attribute-defined-outside-init
        self.schedule.start_date = self.enrollment.created
        self.schedule.save()

        self.user = self.enrollment.user  # lint-amnesty, pylint: disable=attribute-defined-outside-init
コード例 #48
0
    def create_schedule(self, offset=0):
        self.config = ScheduleConfigFactory(create_schedules=True)

        site_patch = patch('openedx.core.djangoapps.schedules.signals.get_current_site', return_value=self.config.site)
        self.addCleanup(site_patch.stop)
        site_patch.start()

        start = datetime.datetime.now(utc) - datetime.timedelta(days=100)
        self.course = CourseFactory.create(start=start, self_paced=True)

        self.enrollment = CourseEnrollmentFactory(
            course_id=self.course.id,
            mode=CourseMode.AUDIT,
        )
        self.enrollment.created = start + datetime.timedelta(days=offset)
        self.enrollment.save()

        self.schedule = self.enrollment.schedule
        self.schedule.start_date = self.enrollment.created
        self.schedule.save()

        self.user = self.enrollment.user
コード例 #49
0
ファイル: test_resolvers.py プロジェクト: mattpe/edx-platform
    def setUp(self):
        super(TestBinnedSchedulesBaseResolver, self).setUp()

        self.site = SiteFactory.create()
        self.site_config = SiteConfigurationFactory.create(site=self.site)
        self.schedule_config = ScheduleConfigFactory.create(site=self.site)
コード例 #50
0
ファイル: test_tasks.py プロジェクト: jolyonb/edx-platform
    def setUp(self):
        super(TestScheduleMessageBaseTask, self).setUp()

        self.site = SiteFactory.create()
        self.schedule_config = ScheduleConfigFactory.create(site=self.site)
        self.basetask = ScheduleMessageBaseTask
コード例 #51
0
    def test_delivery_disabled(self, mock_ace):
        ScheduleConfigFactory.create(site=self.site_config.site, deliver_recurring_nudge=False)

        mock_msg = Mock()
        tasks._recurring_nudge_schedule_send(self.site_config.site.id, mock_msg)
        self.assertFalse(mock_ace.send.called)