def test_get_dates_for_course(self): items = make_items() api.set_dates_for_course(items[0][0].course_key, items) retrieved = api.get_dates_for_course(items[0][0].course_key) assert len(retrieved) == NUM_OVERRIDES first = items[0] assert retrieved[(first[0], 'due')] == first[1]['due'] # second time is cached retrieved = api.get_dates_for_course(items[0][0].course_key) assert len(retrieved) == NUM_OVERRIDES # third time with new course_id course2 = DummyCourse(id='course-v1:testX+tt202+2019') course2.save() new_items = make_items(course2.id) enrollment2 = DummyEnrollment(user=self.user, course=course2) enrollment2.save() schedule2 = DummySchedule(enrollment=enrollment2, start_date=datetime(2019, 4, 1)) schedule2.save() api.set_dates_for_course(new_items[0][0].course_key, new_items) new_retrieved = api.get_dates_for_course(new_items[0][0].course_key) assert len(new_retrieved) == NUM_OVERRIDES first_id = list(new_retrieved.keys())[0][0] last_id = list(retrieved.keys())[0][0] assert first_id.course_key != last_id.course_key return items
def test_set_user_override(self, initial_date, override_date, expected_date): items = make_items() first = items[0] block_id = first[0] items[0][1]['due'] = initial_date api.set_dates_for_course(str(block_id.course_key), items) api.set_date_for_block(block_id.course_key, block_id, 'due', override_date, user=self.user) DEFAULT_REQUEST_CACHE.clear() cache.clear() retrieved = api.get_dates_for_course(block_id.course_key, user=self.user.id) assert len(retrieved) == NUM_OVERRIDES assert retrieved[block_id, 'due'] == expected_date overrides = api.get_overrides_for_block(block_id.course_key, block_id) assert len(overrides) == 1 assert overrides[0][2] == expected_date overrides = list( api.get_overrides_for_user(block_id.course_key, self.user)) assert len(overrides) == 1 assert overrides[0] == { 'location': block_id, 'actual_date': expected_date }
def test_remove_user_override(self, initial_date, override_date, expected_date): items = make_items() first = items[0] block_id = first[0] items[0][1]['due'] = initial_date api.set_dates_for_course(six.text_type(block_id.course_key), items) api.set_date_for_block(block_id.course_key, block_id, 'due', override_date, user=self.user) DEFAULT_REQUEST_CACHE.clear() retrieved = api.get_dates_for_course(block_id.course_key, user=self.user.id) assert len(retrieved) == NUM_OVERRIDES assert retrieved[block_id, 'due'] == expected_date api.set_date_for_block(block_id.course_key, block_id, 'due', None, user=self.user) DEFAULT_REQUEST_CACHE.clear() retrieved = api.get_dates_for_course(block_id.course_key, user=self.user.id) assert len(retrieved) == NUM_OVERRIDES if isinstance(initial_date, timedelta): user_initial_date = self.schedule.start_date + initial_date else: user_initial_date = initial_date assert retrieved[block_id, 'due'] == user_initial_date
def test_get_date_for_block(self): items = make_items() course_id = items[0][0].course_key api.set_dates_for_course(course_id, items) block_id, data = items[0] assert api.get_date_for_block(course_id, block_id, user=self.user) == data['due'] assert api.get_date_for_block(course_id, 'bad', user=self.user) is None
def test_get_dates_for_course_outline(self): items = make_items() course_key = items[0][0].course_key items.append((make_block_id(course_key, block_type='video'), {'start': datetime(2019, 3, 21), 'test': '1'})) api.set_dates_for_course(course_key, items) # Ensure the video block *was* returned normally. retrieved = api.get_dates_for_course( course_key, subsection_and_higher_only=False, published_version=self.course_version ) assert len(retrieved) == NUM_OVERRIDES + 1 # Ensure the video block *was not* returned with subsection and higher blocks. retrieved = api.get_dates_for_course( course_key, subsection_and_higher_only=True, published_version=self.course_version ) assert len(retrieved) == NUM_OVERRIDES # Set all the ContentDates for this course's structural blocks to have # None for their block_type to test compatibilty with a half-migrated # state. They should still be returned by get_dates_for_course with # subsection_and_higher_only=True. structural_dates = models.ContentDate.objects.filter( course_id=course_key, block_type__in=['course', 'chapter', 'sequential'] ) structural_dates.update(block_type=None) retrieved = api.get_dates_for_course( course_key, subsection_and_higher_only=True, published_version=self.course_version, use_cached=False ) assert len(retrieved) == NUM_OVERRIDES
def test_get_dates_no_schedule(self): items = make_items(with_relative=True) course_key = items[0][0].course_key api.set_dates_for_course(course_key, items) retrieved = api.get_dates_for_course(course_key, user=self.user) assert len(retrieved) == 6 self.schedule.delete() retrieved = api.get_dates_for_course(course_key, user=self.user, use_cached=False) assert len(retrieved) == 3
def test_set_user_override_invalid_date(self, initial_date, override_date): items = make_items() first = items[0] block_id = first[0] items[0][1]['due'] = initial_date api.set_dates_for_course(str(block_id.course_key), items) with self.assertRaises(api.InvalidDateError): api.set_date_for_block(block_id.course_key, block_id, 'due', override_date, user=self.user)
def test_set_user_override_invalid_block(self): items = make_items() first = items[0] block_id = first[0] api.set_dates_for_course(str(block_id.course_key), items) with self.assertRaises(api.MissingDateError): # can't set a user override for content without a date bad_block_id = make_block_id() api.set_date_for_block(bad_block_id.course_key, bad_block_id, 'due', datetime(2019, 4, 6), user=self.user)
def test_get_schedules_with_due_date_for_abs_date(self): self.schedule.start_date = datetime(2019, 3, 22) items = make_items(with_relative=False) assignment_date = items[0][1].get('due') api.set_date_for_block(items[0][0].course_key, items[0][0], 'due', assignment_date) # Specify the actual assignment due date so this will return true schedules = api.get_schedules_with_due_date(items[0][0].course_key, datetime.date(assignment_date)) assert len(schedules) > 0 for schedule in schedules: assert schedule.enrollment.course_id == items[0][0].course_key assert schedule.enrollment.user.id == self.user.id
def test_set_date_for_block(self, initial_date, override_date, expected_date): items = make_items() first = items[0] block_id = first[0] items[0][1]['due'] = initial_date api.set_dates_for_course(str(block_id.course_key), items) api.set_date_for_block(block_id.course_key, block_id, 'due', override_date) TieredCache.dangerous_clear_all_tiers() retrieved = api.get_dates_for_course(block_id.course_key, user=self.user.id) assert len(retrieved) == NUM_OVERRIDES assert retrieved[block_id, 'due'] == expected_date
def test_set_dates_for_course_query_counts(self): items = make_items() with self.assertNumQueries(2): # two for transaction wrappers with patch('edx_when.api.set_date_for_block', return_value=1) as mock_set: with patch( 'edx_when.api.clear_dates_for_course') as mock_clear: api.set_dates_for_course(self.course.id, items) self.assertEqual(mock_set.call_count, NUM_OVERRIDES) self.assertEqual(mock_clear.call_args_list, [call(self.course.id, keep=[1] * NUM_OVERRIDES)])
def test_get_user_date_no_schedule(self): items = make_items() course_key = items[0][0].course_key api.set_dates_for_course(course_key, items) before_override = api.get_dates_for_course(course_key, user=self.user) assert len(before_override) == 3 # Override a date for the user with a relative date, but remove the schedule # so that the override can't be applied api.set_date_for_block(course_key, items[0][0], 'due', timedelta(days=2), user=self.user) self.schedule.delete() after_override = api.get_dates_for_course(course_key, user=self.user, use_cached=False) assert before_override == after_override
def test_get_schedules_with_due_date_for_abs_user_dates(self): items = make_items(with_relative=True) api.set_dates_for_course(items[0][0].course_key, items) assignment_date = items[0][1].get('due') api.set_date_for_block(items[0][0].course_key, items[0][0], 'due', assignment_date, user=self.user) models.UserDate.objects.create( abs_date=assignment_date, user=self.user, content_date=models.ContentDate.objects.first(), ) # Specify the actual assignment due date so this will return true schedules = api.get_schedules_with_due_date(items[0][0].course_key, assignment_date.date()) assert len(schedules) == 1 # Make sure there's only one schedule, we should not have duplicates assert schedules[0].enrollment.course_id == items[0][0].course_key assert schedules[0].enrollment.user.id == self.user.id
def test_get_schedules_with_due_date_for_rel_date(self): items = make_items(with_relative=False) api.set_dates_for_course(items[0][0].course_key, items) relative_date = timedelta(days=2) api.set_date_for_block(items[0][0].course_key, items[0][0], 'due', relative_date) assignment_date = items[0][1].get('due') + relative_date # Move the schedule's start to the first assignment's original due since it's now offset self.schedule.start_date = items[0][1].get('due') self.schedule.save() # Specify the actual assignment due date so this will return true schedules = api.get_schedules_with_due_date(items[0][0].course_key, assignment_date.date()) assert len(schedules) > 0 for schedule in schedules: assert schedule.enrollment.course_id == items[0][0].course_key assert schedule.enrollment.user.id == self.user.id
def setUp(self): super().setUp() self.items = make_items(with_relative=True) self.course_id = self.items[0][0].course_key api.set_dates_for_course(self.course_id, self.items) self.user = User(username='******', email='*****@*****.**') self.user.save() schedule = mock.Mock(name="schedule", start_date=datetime.datetime(2019, 4, 1)) mock_Schedule = mock.Mock(name="Schedule") mock_Schedule.objects.get.return_value = schedule schedule_patcher = mock.patch('edx_when.utils.Schedule', mock_Schedule) schedule_patcher.start() self.addCleanup(schedule_patcher.stop)
def test_set_date_for_block(self, initial_date, override_date, expected_date): items = make_items() first = items[0] block_id = first[0] items[0][1]['due'] = initial_date api.set_dates_for_course(str(block_id.course_key), items) api.set_date_for_block(block_id.course_key, block_id, 'due', override_date) DEFAULT_REQUEST_CACHE.clear() cache.clear() retrieved = api.get_dates_for_course(block_id.course_key, user=self.user.id) assert len(retrieved) == NUM_OVERRIDES assert retrieved[block_id, 'due'] == expected_date
def test_remove_user_override(self, initial_date, override_date, expected_date): items = make_items() first = items[0] block_id = first[0] items[0][1]['due'] = initial_date api.set_dates_for_course(str(block_id.course_key), items) api.set_date_for_block(block_id.course_key, block_id, 'due', override_date, user=self.user) TieredCache.dangerous_clear_all_tiers() retrieved = api.get_dates_for_course(block_id.course_key, user=self.user.id) assert len(retrieved) == NUM_OVERRIDES assert retrieved[block_id, 'due'] == expected_date api.set_date_for_block(block_id.course_key, block_id, 'due', None, user=self.user) TieredCache.dangerous_clear_all_tiers() retrieved = api.get_dates_for_course(block_id.course_key, user=self.user.id) assert len(retrieved) == NUM_OVERRIDES if isinstance(initial_date, timedelta): user_initial_date = self.schedule.start_date + initial_date else: user_initial_date = initial_date assert retrieved[block_id, 'due'] == user_initial_date
def test_is_enabled(self): items = make_items() course_id = items[0][0].course_key assert not api.is_enabled_for_course(course_id) api.set_dates_for_course(course_id, items) assert api.is_enabled_for_course(course_id)
def test_set_dates_for_course(self): items = make_items() api.set_dates_for_course(items[0][0].course_key, items) cdates = models.ContentDate.objects.all() assert len(cdates) == NUM_OVERRIDES