def setUp(self): super().setUp() self.course = DummyCourse(id='course-v1:testX+tt101+2019') self.course.save() self.user = User(username='******', email='*****@*****.**') self.user.save() self.enrollment = DummyEnrollment(user=self.user, course=self.course) self.enrollment.save() self.schedule = DummySchedule(enrollment=self.enrollment, start_date=datetime(2019, 4, 1)) self.schedule.save() dummy_schedule_patcher = patch('edx_when.models.Schedule', DummySchedule) dummy_schedule_patcher.start() self.addCleanup(dummy_schedule_patcher.stop) relative_dates_patcher = patch( 'edx_when.api._are_relative_dates_enabled', return_value=True) relative_dates_patcher.start() self.addCleanup(relative_dates_patcher.stop) self.addCleanup(cache.clear) cache.clear() DEFAULT_REQUEST_CACHE.clear()
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_relative_date_past_cutoff_date(self): course_key = CourseLocator('testX', 'tt101', '2019') start_block = make_block_id(course_key, block_type='course') start_date = datetime(2019, 3, 15) first_block = make_block_id(course_key) first_delta = timedelta(days=1) second_block = make_block_id(course_key) second_delta = timedelta(days=10) end_block = make_block_id(course_key, block_type='course') end_date = datetime(2019, 4, 20) items = [ (start_block, { 'start': start_date }), # start dates are always absolute (first_block, { 'due': first_delta }), # relative (second_block, { 'due': second_delta }), # relative (end_block, { 'end': end_date }), # end dates are always absolute ] api.set_dates_for_course(course_key, items) # Try one with just enough as a sanity check self.schedule.created = end_date - second_delta self.schedule.save() dates = [ ((start_block, 'start'), start_date), ((first_block, 'due'), self.schedule.start_date + first_delta), ((second_block, 'due'), self.schedule.start_date + second_delta), ((end_block, 'end'), end_date), ] assert api.get_dates_for_course(course_key, schedule=self.schedule) == dict(dates) cache.clear() DEFAULT_REQUEST_CACHE.clear() # Now set schedule start date too close to the end date and verify that we no longer get due dates self.schedule.created = datetime(2019, 4, 15) self.schedule.save() dates = [ ((start_block, 'start'), start_date), ((first_block, 'due'), None), ((second_block, 'due'), None), ((end_block, 'end'), end_date), ] assert api.get_dates_for_course(course_key, schedule=self.schedule) == dict(dates)
def test_get_dates_for_course_query_counts(self, has_schedule, pass_user_object, pass_schedule, item_count): if not has_schedule: self.schedule.delete() items = [(make_block_id(self.course.id), { 'due': datetime(2020, 1, 1) + timedelta(days=i) }) for i in range(item_count)] api.set_dates_for_course(self.course.id, items) user = self.user if pass_user_object else self.user.id schedule = self.schedule if pass_schedule and has_schedule else None if has_schedule and pass_schedule: query_count = 2 else: query_count = 3 with self.assertNumQueries(query_count): dates = api.get_dates_for_course(course_id=self.course.id, user=user, schedule=schedule) # Second time, the request cache eliminates all querying... with self.assertNumQueries(0): cached_dates = api.get_dates_for_course(course_id=self.course.id, user=user, schedule=schedule) assert dates == cached_dates # Now wipe the request cache... DEFAULT_REQUEST_CACHE.clear() # This time, test the external cache (which eliminates the one large # query to ContentDates). with self.assertNumQueries(query_count - 1): externally_cached_dates = api.get_dates_for_course( course_id=self.course.id, user=user, schedule=schedule) assert dates == externally_cached_dates # Finally, force uncached behavior with used_cache=False with self.assertNumQueries(query_count): uncached_dates = api.get_dates_for_course(course_id=self.course.id, user=user, schedule=schedule, use_cached=False) assert dates == uncached_dates
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