Esempio n. 1
0
    def setUp(self):
        super().setUp()

        self.course = DummyCourse(id='course-v1:testX+tt101+2019')
        self.course.save()

        self.course_version = 'TEST_VERSION'

        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, created=datetime(2019, 4, 1), start_date=datetime(2019, 4, 1)
        )
        self.schedule.save()

        dummy_schedule_patcher = patch('edx_when.utils.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(TieredCache.dangerous_clear_all_tiers)

        TieredCache.dangerous_clear_all_tiers()
Esempio n. 2
0
 def clear_caches(cls):
     """
     Clear all of the caches defined in settings.CACHES.
     """
     # N.B. As of 2016-04-20, Django won't return any caches
     # from django.core.cache.caches.all() that haven't been
     # accessed using caches[name] previously, so we loop
     # over our list of overridden caches, instead.
     for cache in settings.CACHES:
         caches[cache].clear()
     TieredCache.dangerous_clear_all_tiers()
Esempio n. 3
0
    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_with_unsupported_routing_strategy(self, mocked_logger,
                                               mocked_post):
        RouterConfigurationFactory.create(
            backend_name='test_backend',
            enabled=True,
            route_url='http://test3.com',
            auth_scheme=RouterConfiguration.AUTH_BEARER,
            auth_key='test_key',
            configurations=ROUTER_CONFIG_FIXTURE[0])

        router = EventsRouter(processors=[], backend_name='test_backend')
        TieredCache.dangerous_clear_all_tiers()
        router.send(self.transformed_event)

        mocked_logger.error.assert_called_once_with(
            'Unsupported routing strategy detected: INVALID_TYPE')
        mocked_post.assert_not_called()
Esempio n. 5
0
    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 (sometimes)...
        # If a schedule is not provided, we will get the schedule to avoid caching outdated dates
        with self.assertNumQueries(0 if schedule else 1):
            cached_dates = api.get_dates_for_course(
                course_id=self.course.id, user=user, schedule=schedule
            )
            assert dates == cached_dates

        # Now wipe all cache tiers...
        TieredCache.dangerous_clear_all_tiers()

        # No cached values - so will do *all* queries again.
        with self.assertNumQueries(query_count):
            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_with_no_available_hosts(self, mocked_logger, mocked_post):
        router_config = RouterConfigurationFactory.create(
            backend_name='test_backend',
            enabled=True,
            route_url='http://test3.com',
            configurations=ROUTER_CONFIG_FIXTURE[1])

        router = EventsRouter(processors=[], backend_name='test_backend')
        TieredCache.dangerous_clear_all_tiers()
        router.send(self.transformed_event)

        mocked_post.assert_not_called()

        self.assertIn(
            call(
                'Event %s is not allowed to be sent to any host for router %s with backend "%s"',
                self.transformed_event['name'], router_config.route_url,
                'test_backend'), mocked_logger.info.mock_calls)
Esempio n. 7
0
    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)

        TieredCache.dangerous_clear_all_tiers()

        # 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)
Esempio n. 8
0
    def test_enabled_router_is_returned(self):
        first_router = RouterConfigurationFactory(configurations='{}',
                                                  enabled=True,
                                                  route_url='http://test2.com',
                                                  backend_name='first')
        second_router = RouterConfigurationFactory(
            configurations='{}',
            enabled=False,
            route_url='http://test3.com',
            backend_name='second')
        self.assertEqual(
            RouterConfiguration.get_enabled_routers('first')[0], first_router)
        self.assertEqual(RouterConfiguration.get_enabled_routers('second'),
                         None)

        second_router.enabled = True
        second_router.save()
        TieredCache.dangerous_clear_all_tiers()
        self.assertEqual(
            RouterConfiguration.get_enabled_routers('second')[0],
            second_router)
Esempio n. 9
0
    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)
        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

        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}
Esempio n. 10
0
    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
Esempio n. 11
0
 def test_dangerous_clear_all_tiers_and_namespaces(self, mock_cache_clear):
     TieredCache.set_all_tiers(TEST_KEY, EXPECTED_VALUE)
     TieredCache.dangerous_clear_all_tiers()
     self.assertFalse(
         self.request_cache.get_cached_response(TEST_KEY).is_found)
     mock_cache_clear.assert_called_once_with()
Esempio n. 12
0
 def setUp(self):
     super().setUp()
     self.request_cache = RequestCache()
     TieredCache.dangerous_clear_all_tiers()
    def test_successful_routing_of_event(
        self,
        auth_scheme,
        auth_key,
        username,
        password,
        backend_name,
        route_url,
        mocked_lrs,
        mocked_post,
    ):
        TieredCache.dangerous_clear_all_tiers()
        mocked_oauth_client = MagicMock()
        mocked_api_key_client = MagicMock()

        MOCKED_MAP = {
            'AUTH_HEADERS': HttpClient,
            'OAUTH2': mocked_oauth_client,
            'API_KEY': mocked_api_key_client,
            'XAPI_LRS': LrsClient,
        }
        RouterConfigurationFactory.create(
            backend_name=backend_name,
            enabled=True,
            route_url=route_url,
            auth_scheme=auth_scheme,
            auth_key=auth_key,
            username=username,
            password=password,
            configurations=ROUTER_CONFIG_FIXTURE[0])

        router = EventsRouter(processors=[], backend_name=backend_name)

        with patch.dict('event_routing_backends.tasks.ROUTER_STRATEGY_MAPPING',
                        MOCKED_MAP):
            router.send(self.transformed_event)

        overridden_event = self.transformed_event.copy()
        overridden_event['new_key'] = 'new_value'

        if backend_name == RouterConfiguration.XAPI_BACKEND:
            # test LRS Client
            mocked_lrs().save_statement.assert_has_calls([
                call(overridden_event),
            ])
        else:
            # test the HTTP client
            if auth_scheme == RouterConfiguration.AUTH_BASIC:
                mocked_post.assert_has_calls([
                    call(url=route_url,
                         json=overridden_event,
                         headers={},
                         auth=(username, password)),
                ])
            elif auth_scheme == RouterConfiguration.AUTH_BEARER:
                mocked_post.assert_has_calls([
                    call(url=route_url,
                         json=overridden_event,
                         headers={
                             'Authorization':
                             RouterConfiguration.AUTH_BEARER + ' ' + auth_key
                         }),
                ])
            else:
                mocked_post.assert_has_calls([
                    call(
                        url=route_url,
                        json=overridden_event,
                        headers={},
                    ),
                ])

        # test mocked oauth client
        mocked_oauth_client.assert_not_called()