def setUp(self): super(SiteMixin, self).setUp() self.site = SiteFactory.create() self.site_configuration = SiteConfigurationFactory.create( site=self.site, values={ "SITE_NAME": self.site.domain, "course_email_from_addr": "*****@*****.**", "course_email_template_name": "fake_email_template", "course_org_filter": "fakeX" } ) self.site_other = SiteFactory.create( domain='testserver.fakeother', name='testserver.fakeother' ) self.site_configuration_other = SiteConfigurationFactory.create( site=self.site_other, values={ "SITE_NAME": self.site_other.domain, "SESSION_COOKIE_DOMAIN": self.site_other.domain, "course_org_filter": "fakeOtherX", "ENABLE_MKTG_SITE": True, "SHOW_ECOMMERCE_REPORTS": True, "MKTG_URLS": { "ROOT": "https://marketing.fakeother", "ABOUT": "/fake-about" } } ) # Initialize client with default site domain self.use_site(self.site)
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)
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)
def test_no_entry_is_saved_for_errors(self): """ Test that and entry is not added to SiteConfigurationHistory if there is an error while saving SiteConfiguration. """ # add SiteConfiguration to database site_configuration = SiteConfigurationFactory.create( site=self.site, ) # Verify an entry to SiteConfigurationHistory was added. site_configuration_history = SiteConfigurationHistory.objects.filter( site=site_configuration.site, ).all() # Make sure entry is saved if there is no error self.assertEqual(len(site_configuration_history), 1) with transaction.atomic(): with self.assertRaises(IntegrityError): # try to add a duplicate entry site_configuration = SiteConfigurationFactory.create( site=self.site, ) site_configuration_history = SiteConfigurationHistory.objects.filter( site=site_configuration.site, ).all() # Make sure no entry is saved if there an error self.assertEqual(len(site_configuration_history), 1)
def test_get_site_for_org(self): """ Test that get_value_for_org returns correct value for any given key. """ # add SiteConfiguration to database config1 = SiteConfigurationFactory.create( site=self.site, values=self.test_config1, ) config2 = SiteConfigurationFactory.create( site=self.site2, values=self.test_config2, ) # Make sure entry is saved and retrieved correctly self.assertEqual( SiteConfiguration.get_configuration_for_org(self.test_config1['course_org_filter']), config1, ) self.assertEqual( SiteConfiguration.get_configuration_for_org(self.test_config2['course_org_filter']), config2, ) self.assertEqual( SiteConfiguration.get_configuration_for_org('something else'), None, )
def test_get_course_org_filter_exclude__in(self, course_org_filter, expected_org_list): SiteConfigurationFactory.create( values={'course_org_filter': course_org_filter}, ) mock_query = Mock() result = self.resolver.filter_by_org(mock_query) mock_query.exclude.assert_called_once_with(enrollment__course__org__in=expected_org_list) self.assertEqual(result, mock_query.exclude.return_value)
def test_get_all_orgs(self): """ Test that get_all_orgs returns all orgs from site configuration. """ expected_orgs = [self.test_config1["course_org_filter"], self.test_config2["course_org_filter"]] # add SiteConfiguration to database SiteConfigurationFactory.create(site=self.site, values=self.test_config1) SiteConfigurationFactory.create(site=self.site2, values=self.test_config2) # Test that the default value is returned if the value for the given key is not found in the configuration self.assertListEqual(list(SiteConfiguration.get_all_orgs()), expected_orgs)
def test_get_all_orgs_returns_only_enabled(self): """ Test that get_all_orgs returns only those orgs whose configurations are enabled. """ expected_orgs = [self.test_config2["course_org_filter"]] # add SiteConfiguration to database SiteConfigurationFactory.create(site=self.site, values=self.test_config1, enabled=False) SiteConfigurationFactory.create(site=self.site2, values=self.test_config2) # Test that the default value is returned if the value for the given key is not found in the configuration self.assertListEqual(list(SiteConfiguration.get_all_orgs()), expected_orgs)
def test_config_overrides(self, global_setting, site_setting, org_setting, course_setting, reverse_order): """ Test that the stacked configuration overrides happen in the correct order and priority. This is tested by exhaustively setting each combination of contexts, and validating that only the lowest level context that is set to not-None is applied. """ # Add a bunch of configuration outside the contexts that are being tested, to make sure # there are no leaks of configuration across contexts non_test_course_enabled = CourseOverviewFactory.create(org='non-test-org-enabled') non_test_course_disabled = CourseOverviewFactory.create(org='non-test-org-disabled') non_test_site_cfg_enabled = SiteConfigurationFactory.create( values={'course_org_filter': non_test_course_enabled.org} ) non_test_site_cfg_disabled = SiteConfigurationFactory.create( values={'course_org_filter': non_test_course_disabled.org} ) CourseDurationLimitConfig.objects.create(course=non_test_course_enabled, enabled=True) CourseDurationLimitConfig.objects.create(course=non_test_course_disabled, enabled=False) CourseDurationLimitConfig.objects.create(org=non_test_course_enabled.org, enabled=True) CourseDurationLimitConfig.objects.create(org=non_test_course_disabled.org, enabled=False) CourseDurationLimitConfig.objects.create(site=non_test_site_cfg_enabled.site, enabled=True) CourseDurationLimitConfig.objects.create(site=non_test_site_cfg_disabled.site, enabled=False) # Set up test objects test_course = CourseOverviewFactory.create(org='test-org') test_site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': test_course.org}) if reverse_order: CourseDurationLimitConfig.objects.create(site=test_site_cfg.site, enabled=site_setting) CourseDurationLimitConfig.objects.create(org=test_course.org, enabled=org_setting) CourseDurationLimitConfig.objects.create(course=test_course, enabled=course_setting) CourseDurationLimitConfig.objects.create(enabled=global_setting) else: CourseDurationLimitConfig.objects.create(enabled=global_setting) CourseDurationLimitConfig.objects.create(course=test_course, enabled=course_setting) CourseDurationLimitConfig.objects.create(org=test_course.org, enabled=org_setting) CourseDurationLimitConfig.objects.create(site=test_site_cfg.site, enabled=site_setting) expected_global_setting = self._resolve_settings([global_setting]) expected_site_setting = self._resolve_settings([global_setting, site_setting]) expected_org_setting = self._resolve_settings([global_setting, site_setting, org_setting]) expected_course_setting = self._resolve_settings([global_setting, site_setting, org_setting, course_setting]) self.assertEqual(expected_global_setting, CourseDurationLimitConfig.current().enabled) self.assertEqual(expected_site_setting, CourseDurationLimitConfig.current(site=test_site_cfg.site).enabled) self.assertEqual(expected_org_setting, CourseDurationLimitConfig.current(org=test_course.org).enabled) self.assertEqual(expected_course_setting, CourseDurationLimitConfig.current(course_key=test_course.id).enabled)
def test_caching_org(self): course = CourseOverviewFactory.create(org='test-org') site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': course.org}) org_config = ContentTypeGatingConfig(org=course.org, enabled=True, enabled_as_of=datetime(2018, 1, 1)) org_config.save() # Check that the org value is not retrieved from cache after save with self.assertNumQueries(2): self.assertTrue(ContentTypeGatingConfig.current(org=course.org).enabled) # Check that the org value can be retrieved from cache after read with self.assertNumQueries(0): self.assertTrue(ContentTypeGatingConfig.current(org=course.org).enabled) org_config.enabled = False org_config.save() # Check that the org value in cache was deleted on save with self.assertNumQueries(2): self.assertFalse(ContentTypeGatingConfig.current(org=course.org).enabled) global_config = ContentTypeGatingConfig(enabled=True, enabled_as_of=datetime(2018, 1, 1)) global_config.save() # Check that the org value is not updated in cache by changing the global value with self.assertNumQueries(0): self.assertFalse(ContentTypeGatingConfig.current(org=course.org).enabled) site_config = ContentTypeGatingConfig(site=site_cfg.site, enabled=True, enabled_as_of=datetime(2018, 1, 1)) site_config.save() # Check that the org value is not updated in cache by changing the site value with self.assertNumQueries(0): self.assertFalse(ContentTypeGatingConfig.current(org=course.org).enabled)
def test_comment_created_signal_sends_message(self, mock_send_message, mock_get_current_site): site_config = SiteConfigurationFactory.create(site=self.site) site_config.values[ENABLE_FORUM_NOTIFICATIONS_FOR_SITE_KEY] = True site_config.save() mock_get_current_site.return_value = self.site signals.comment_created.send(sender=self.sender, user=self.user, post=self.post) mock_send_message.assert_called_once_with(self.post, mock_get_current_site.return_value)
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)
def test_site_config_override(self): site_config = SiteConfigurationFactory.create( values=dict( GOOGLE_ANALYTICS_ACCOUNT='UA-654321-1' ) ) pixel = GoogleAnalyticsTrackingPixel(site=site_config.site) self.assert_query_string_parameters_equal(pixel.generate_image_url(), tid='UA-654321-1')
def test_site(self, mock_grade_interesting, mock_cert_change): site_config = SiteConfigurationFactory.create( values={'course_org_filter': ['testX']}, ) call_command(Command(), '--site', site_config.site.domain, '--start-date', '2017-01-01') self.assertEqual(mock_grade_interesting.call_count, 1) self.assertEqual(mock_cert_change.call_count, 1)
def test_all_current_course_configs(self): # Set up test objects for global_setting in (True, False, None): CourseDurationLimitConfig.objects.create(enabled=global_setting, enabled_as_of=datetime(2018, 1, 1)) for site_setting in (True, False, None): test_site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': []}) CourseDurationLimitConfig.objects.create( site=test_site_cfg.site, enabled=site_setting, enabled_as_of=datetime(2018, 1, 1) ) for org_setting in (True, False, None): test_org = "{}-{}".format(test_site_cfg.id, org_setting) test_site_cfg.values['course_org_filter'].append(test_org) test_site_cfg.save() CourseDurationLimitConfig.objects.create( org=test_org, enabled=org_setting, enabled_as_of=datetime(2018, 1, 1) ) for course_setting in (True, False, None): test_course = CourseOverviewFactory.create( org=test_org, id=CourseLocator(test_org, 'test_course', 'run-{}'.format(course_setting)) ) CourseDurationLimitConfig.objects.create( course=test_course, enabled=course_setting, enabled_as_of=datetime(2018, 1, 1) ) with self.assertNumQueries(4): all_configs = CourseDurationLimitConfig.all_current_course_configs() # Deliberatly using the last all_configs that was checked after the 3rd pass through the global_settings loop # We should be creating 3^4 courses (3 global values * 3 site values * 3 org values * 3 course values) # Plus 1 for the edX/toy/2012_Fall course self.assertEqual(len(all_configs), 3**4 + 1) # Point-test some of the final configurations self.assertEqual( all_configs[CourseLocator('7-True', 'test_course', 'run-None')], { 'enabled': (True, Provenance.org), 'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run), } ) self.assertEqual( all_configs[CourseLocator('7-True', 'test_course', 'run-False')], { 'enabled': (False, Provenance.run), 'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run), } ) self.assertEqual( all_configs[CourseLocator('7-None', 'test_course', 'run-None')], { 'enabled': (True, Provenance.site), 'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run), } )
def setUpClass(cls): super(TestHubspotSyncCommand, cls).setUpClass() cls.site_config = SiteConfigurationFactory() cls.hubspot_site_config = SiteConfigurationFactory.create( values={'HUBSPOT_API_KEY': 'test_key'}, ) cls.users = [] cls._create_users(cls.hubspot_site_config) # users for a site with hubspot integration enabled cls._create_users(cls.site_config)
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)
def test_comment_created_signal_msg_not_sent_with_site_config_disabled( self, mock_send_message, mock_get_current_site ): site_config = SiteConfigurationFactory.create(site=self.site) site_config.values[ENABLE_FORUM_NOTIFICATIONS_FOR_SITE_KEY] = False site_config.save() mock_get_current_site.return_value = self.site signals.comment_created.send(sender=self.sender, user=self.user, post=self.post) self.assertFalse(mock_send_message.called)
def test_get_course_org_filter_exclude(self, course_org_filter, expected_org_list): resolver = self.setup_resolver() self.other_site = SiteFactory.create() self.other_site_config = SiteConfigurationFactory.create( site=self.other_site, values={'course_org_filter': course_org_filter}, ) exclude_orgs, org_list = resolver.get_course_org_filter() assert exclude_orgs self.assertItemsEqual(org_list, expected_org_list)
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()
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)
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)
def test_send_discussion_email_notification(self, user_subscribed): if user_subscribed: non_matching_id = 'not-a-match' # with per_page left with a default value of 1, this ensures # that we test a multiple page result when calling # comment_client.User.subscribed_threads() subscribed_thread_ids = [non_matching_id, self.discussion_id] else: subscribed_thread_ids = [] self.mock_request.side_effect = make_mock_responder( subscribed_thread_ids=subscribed_thread_ids, comment_data=self.comment, thread_data=self.thread, ) user = mock.Mock() comment = cc.Comment.find(id=self.comment['id']).retrieve() site = Site.objects.get_current() site_config = SiteConfigurationFactory.create(site=site) site_config.values[ENABLE_FORUM_NOTIFICATIONS_FOR_SITE_KEY] = True site_config.save() with mock.patch('lms.djangoapps.discussion.signals.handlers.get_current_site', return_value=site): comment_created.send(sender=None, user=user, post=comment) if user_subscribed: expected_message_context = get_base_template_context(site) expected_message_context.update({ 'comment_author_id': self.comment_author.id, 'comment_body': self.comment['body'], 'comment_created_at': ONE_HOUR_AGO, 'comment_id': self.comment['id'], 'comment_username': self.comment_author.username, 'course_id': self.course.id, 'thread_author_id': self.thread_author.id, 'thread_created_at': TWO_HOURS_AGO, 'thread_id': self.discussion_id, 'thread_title': 'thread-title', 'thread_username': self.thread_author.username, 'thread_commentable_id': self.thread['commentable_id'], 'post_link': self.mock_permalink.return_value, 'site': site, 'site_id': site.id }) expected_recipient = Recipient(self.thread_author.username, self.thread_author.email) actual_message = self.mock_ace_send.call_args_list[0][0][0] self.assertEqual(expected_message_context, actual_message.context) self.assertEqual(expected_recipient, actual_message.recipient) self.assertEqual(self.course.language, actual_message.language) self._assert_rendered_email(actual_message) else: self.assertFalse(self.mock_ace_send.called)
def test_site_configuration_post_save_receiver(self): """ Test that and entry is added to SiteConfigurationHistory model each time a new SiteConfiguration is added. """ # add SiteConfiguration to database site_configuration = SiteConfigurationFactory.create(site=self.site) # Verify an entry to SiteConfigurationHistory was added. site_configuration_history = SiteConfigurationHistory.objects.filter(site=site_configuration.site).all() # Make sure an entry (and only one entry) is saved for SiteConfiguration self.assertEqual(len(site_configuration_history), 1)
def configure_commerce(self, is_configured, is_default_page): """ Helper for creating specific Commerce Configuration. Arguments: is_configured (bool): Indicates whether or not the Site has Site Configuration. is_default_page (bool): Indicates whether or not the LMS receipt page is used Returns: Commerce configuration. """ if not is_default_page: if is_configured: SiteConfigurationFactory.create( site=self.site, receipt_page_url='receipt/page/url', ) return CommerceConfiguration.objects.create( enabled=True, site=self.site if not is_default_page else None )
def set_up_site(self, domain, site_configuration_values): """ Create Site and SiteConfiguration models and initialize test client with the created site """ site = SiteFactory.create( domain=domain, name=domain ) __ = SiteConfigurationFactory.create( site=site, values=site_configuration_values ) self.use_site(site)
def test_send_grade_records_enabled(self, _mock_is_course_run_in_a_program, mock_send_grade_to_credentials, _mock_is_learner_issuance_enabled): site_config = SiteConfigurationFactory.create( values={'course_org_filter': [self.key.org]}, ) # Correctly sent send_grade_if_interesting(self.user, self.key, 'verified', 'downloadable', None, None) self.assertTrue(mock_send_grade_to_credentials.delay.called) mock_send_grade_to_credentials.delay.reset_mock() # Correctly not sent site_config.values['ENABLE_LEARNER_RECORDS'] = False site_config.save() send_grade_if_interesting(self.user, self.key, 'verified', 'downloadable', None, None) self.assertFalse(mock_send_grade_to_credentials.delay.called)
def test_site_configuration_post_update_receiver(self): """ Test that and entry is added to SiteConfigurationHistory each time a SiteConfiguration is updated. """ # add SiteConfiguration to database site_configuration = SiteConfigurationFactory.create(site=self.site) site_configuration.values = {"test": "test"} site_configuration.save() # Verify an entry to SiteConfigurationHistory was added. site_configuration_history = SiteConfigurationHistory.objects.filter(site=site_configuration.site).all() # Make sure two entries (one for save and one for update) are saved for SiteConfiguration self.assertEqual(len(site_configuration_history), 2)
def test_records_enabled(self, mock_is_learner_issuance_enabled, mock_task): mock_is_learner_issuance_enabled.return_value = True site_config = SiteConfigurationFactory.create( values={'course_org_filter': ['edX']}, ) # Correctly sent handle_course_cert_changed(**self.signal_kwargs) self.assertTrue(mock_task.called) mock_task.reset_mock() # Correctly not sent site_config.values['ENABLE_LEARNER_RECORDS'] = False site_config.save() handle_course_cert_changed(**self.signal_kwargs) self.assertFalse(mock_task.called)
def setUp(self): super(SessionCookieDomainSiteConfigurationOverrideTests, self).setUp() # Create a test client, and log it in so that it will save some session data. self.user = UserFactory.create() self.user.set_password('password') self.user.save() self.site = SiteFactory.create( domain='testserver.fake', name='testserver.fake' ) self.site_configuration = SiteConfigurationFactory.create( site=self.site, values={ "SESSION_COOKIE_DOMAIN": self.site.domain, } ) self.client = Client() self.client.login(username=self.user.username, password="******")
def test_send_grade_records_enabled(self, _mock_is_course_run_in_a_program, mock_send_grade_to_credentials, _mock_is_learner_issuance_enabled): site_config = SiteConfigurationFactory.create( values={'course_org_filter': [self.key.org]}, ) # Correctly sent send_grade_if_interesting(self.user, self.key, 'verified', 'downloadable', None, None) self.assertTrue(mock_send_grade_to_credentials.delay.called) mock_send_grade_to_credentials.delay.reset_mock() # Correctly not sent site_config.values['ENABLE_LEARNER_RECORDS'] = False site_config.save() send_grade_if_interesting(self.user, self.key, 'verified', 'downloadable', None, None) self.assertFalse(mock_send_grade_to_credentials.delay.called)
def setUp(self): super(SessionCookieDomainSiteConfigurationOverrideTests, self).setUp() # Create a test client, and log it in so that it will save some session data. self.user = UserFactory.create() self.user.set_password('password') self.user.save() self.site = SiteFactory.create( domain='testserver.fake', name='testserver.fake' ) self.site_configuration = SiteConfigurationFactory.create( site=self.site, values={ "SESSION_COOKIE_DOMAIN": self.site.domain, } ) self.client = Client() self.client.login(username=self.user.username, password="******")
def test_caching_org(self): course = CourseOverviewFactory.create(org='test-org') site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': course.org}) org_config = CourseDurationLimitConfig(org=course.org, enabled=True, enabled_as_of=datetime(2018, 1, 1)) org_config.save() RequestCache.clear_all_namespaces() # Check that the org value is not retrieved from cache after save with self.assertNumQueries(2): self.assertTrue(CourseDurationLimitConfig.current(org=course.org).enabled) RequestCache.clear_all_namespaces() # Check that the org value can be retrieved from cache after read with self.assertNumQueries(0): self.assertTrue(CourseDurationLimitConfig.current(org=course.org).enabled) org_config.enabled = False org_config.save() RequestCache.clear_all_namespaces() # Check that the org value in cache was deleted on save with self.assertNumQueries(2): self.assertFalse(CourseDurationLimitConfig.current(org=course.org).enabled) global_config = CourseDurationLimitConfig(enabled=True, enabled_as_of=datetime(2018, 1, 1)) global_config.save() RequestCache.clear_all_namespaces() # Check that the org value is not updated in cache by changing the global value with self.assertNumQueries(0): self.assertFalse(CourseDurationLimitConfig.current(org=course.org).enabled) site_config = CourseDurationLimitConfig(site=site_cfg.site, enabled=True, enabled_as_of=datetime(2018, 1, 1)) site_config.save() RequestCache.clear_all_namespaces() # Check that the org value is not updated in cache by changing the site value with self.assertNumQueries(0): self.assertFalse(CourseDurationLimitConfig.current(org=course.org).enabled)
def test_records_enabled(self, mock_is_learner_issuance_enabled, mock_task): mock_is_learner_issuance_enabled.return_value = True site_config = SiteConfigurationFactory.create( site_values={'course_org_filter': ['edX']}, values={'course_org_filter': ['edX']}, ) # Correctly sent handle_course_cert_changed(**self.signal_kwargs) self.assertTrue(mock_task.called) mock_task.reset_mock() # Correctly not sent site_config.values['ENABLE_LEARNER_RECORDS'] = False site_config.save() handle_course_cert_changed(**self.signal_kwargs) self.assertFalse(mock_task.called)
def test_site_configuration_post_update_receiver(self): """ Test that and entry is added to SiteConfigurationHistory each time a SiteConfiguration is updated. """ # add SiteConfiguration to database site_configuration = SiteConfigurationFactory.create(site=self.site, ) site_configuration.site_values = {'test': 'test'} # TODO: Remove this deprecated value eventually. site_configuration.values = {'test': 'test'} site_configuration.save() # Verify an entry to SiteConfigurationHistory was added. site_configuration_history = SiteConfigurationHistory.objects.filter( site=site_configuration.site, ).all() # Make sure two entries (one for save and one for update) are saved for SiteConfiguration self.assertEqual(len(site_configuration_history), 2)
def setUp(self): super().setUp() freezer = freeze_time(datetime(2013, 10, 3, 8, 24, 55, tzinfo=pytz.utc)) self.addCleanup(freezer.stop) freezer.start() self.course = CourseOverviewFactory() self.user = UserFactory() self.request = RequestFactory().request() self.request.site = SiteFactory() self.request.user = self.user self.site_config = SiteConfigurationFactory.create( site_values={'course_org_filter': self.course.org} ) self.user_calendar_sync_config = UserCalendarSyncConfigFactory.create( user=self.user, course_key=self.course.id, )
def test_caching_course(self): course = CourseOverviewFactory.create(org='test-org') site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': course.org}) course_config = ContentTypeGatingConfig(course=course, enabled=True, enabled_as_of=date(2018, 1, 1)) course_config.save() # Check that the org value is not retrieved from cache after save with self.assertNumQueries(2): self.assertTrue(ContentTypeGatingConfig.current(course_key=course.id).enabled) # Check that the org value can be retrieved from cache after read with self.assertNumQueries(0): self.assertTrue(ContentTypeGatingConfig.current(course_key=course.id).enabled) course_config.enabled = False course_config.save() # Check that the org value in cache was deleted on save with self.assertNumQueries(2): self.assertFalse(ContentTypeGatingConfig.current(course_key=course.id).enabled) global_config = ContentTypeGatingConfig(enabled=True, enabled_as_of=date(2018, 1, 1)) global_config.save() # Check that the org value is not updated in cache by changing the global value with self.assertNumQueries(0): self.assertFalse(ContentTypeGatingConfig.current(course_key=course.id).enabled) site_config = ContentTypeGatingConfig(site=site_cfg.site, enabled=True, enabled_as_of=date(2018, 1, 1)) site_config.save() # Check that the org value is not updated in cache by changing the site value with self.assertNumQueries(0): self.assertFalse(ContentTypeGatingConfig.current(course_key=course.id).enabled) org_config = ContentTypeGatingConfig(org=course.org, enabled=True, enabled_as_of=date(2018, 1, 1)) org_config.save() # Check that the org value is not updated in cache by changing the site value with self.assertNumQueries(0): self.assertFalse(ContentTypeGatingConfig.current(course_key=course.id).enabled)
def test_site_configuration_post_update_receiver_with_skip(self): """ Test that and entry is NOT added to SiteConfigurationHistory each time a SiteConfiguration is updated with save_siteconfig_without_historical_record(). """ # Add SiteConfiguration to database. By default, the site_valutes field contains only "{}". site_configuration = SiteConfigurationFactory.create(site=self.site, ) # Update the SiteConfiguration we just created. site_configuration.site_values = {"test": "test"} save_siteconfig_without_historical_record( site_configuration) # Instead of .save(). # Verify that the SiteConfiguration has been updated. self.assertEqual(site_configuration.get_value("test"), "test") # Verify an entry to SiteConfigurationHistory was NOT added. # Make sure one entry (one for create and NONE for update) is saved for SiteConfiguration. site_configuration_history = SiteConfigurationHistory.objects.filter( site=site_configuration.site, ).all() self.assertEqual(len(site_configuration_history), 1)
def test_from_address_in_send_email(self, mock_site_configuration, mock_get_current_site, mock_log): """ Tests that the "from_address" is pulled from the site configuration. """ site = SiteFactory.create() mock_get_current_site.return_value = site expected_from_email_address = '*****@*****.**' site_config = SiteConfigurationFactory.create( site=site, site_values={ 'ACTIVATION_EMAIL_FROM_ADDRESS': expected_from_email_address }) mock_site_configuration.return_value = site_config compose_and_send_activation_email(self.student, self.student.profile, self.student.registration) mock_log.exception.assert_called_with( 'Unable to send activation email to user from "%s" to "%s"', expected_from_email_address, self.student.email, )
def test_invalid_data_error_on_get_value(self): """ Test that get_value logs an error if json data is not valid. """ # import logger, for patching from openedx.core.djangoapps.site_configuration.models import logger invalid_data = [self.test_config1] # add SiteConfiguration to database site_configuration = SiteConfigurationFactory.create( site=self.site, site_values=invalid_data) # make sure get_value logs an error for invalid json data with patch.object(logger, "exception") as mock_logger: self.assertEqual(site_configuration.get_value("university"), None) self.assertTrue(mock_logger.called) # make sure get_value returns default_value for invalid json data with patch.object(logger, "exception") as mock_logger: value = site_configuration.get_value("platform_name", "Default Platform Name") self.assertTrue(mock_logger.called) self.assertEqual(value, "Default Platform Name")
def test_all_current_course_configs(self): # Set up test objects for global_setting in (True, False, None): ContentTypeGatingConfig.objects.create(enabled=global_setting, enabled_as_of=datetime(2018, 1, 1)) for site_setting in (True, False, None): test_site_cfg = SiteConfigurationFactory.create( site_values={'course_org_filter': []} ) ContentTypeGatingConfig.objects.create(site=test_site_cfg.site, enabled=site_setting, enabled_as_of=datetime(2018, 1, 1)) for org_setting in (True, False, None): test_org = "{}-{}".format(test_site_cfg.id, org_setting) test_site_cfg.site_values['course_org_filter'].append(test_org) test_site_cfg.save() ContentTypeGatingConfig.objects.create(org=test_org, enabled=org_setting, enabled_as_of=datetime(2018, 1, 1)) for course_setting in (True, False, None): test_course = CourseOverviewFactory.create( org=test_org, id=CourseLocator(test_org, 'test_course', 'run-{}'.format(course_setting)) ) ContentTypeGatingConfig.objects.create(course=test_course, enabled=course_setting, enabled_as_of=datetime(2018, 1, 1)) with self.assertNumQueries(4): all_configs = ContentTypeGatingConfig.all_current_course_configs() # Deliberatly using the last all_configs that was checked after the 3rd pass through the global_settings loop # We should be creating 3^4 courses (3 global values * 3 site values * 3 org values * 3 course values) # Plus 1 for the edX/toy/2012_Fall course assert len(all_configs) == ((3 ** 4) + 1) # Point-test some of the final configurations assert all_configs[CourseLocator('7-True', 'test_course', 'run-None')] == {'enabled': (True, Provenance.org), 'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run), 'studio_override_enabled': (None, Provenance.default)} assert all_configs[CourseLocator('7-True', 'test_course', 'run-False')] == {'enabled': (False, Provenance.run), 'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run), 'studio_override_enabled': (None, Provenance.default)} assert all_configs[CourseLocator('7-None', 'test_course', 'run-None')] == {'enabled': (True, Provenance.site), 'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run), 'studio_override_enabled': (None, Provenance.default)}
def _make_site_config(self, enable_feature): site_config = SiteConfigurationFactory.create(site=self.site) site_config.values[waffle.ENABLE_SITE_VISUAL_PROGRESS] = enable_feature site_config.save()
def setUp(self): self.command = SendEmailBaseCommand() self.site = SiteFactory() self.site_config = SiteConfigurationFactory.create(site=self.site)
def test_send_discussion_email_notification(self, user_subscribed): if user_subscribed: non_matching_id = 'not-a-match' # with per_page left with a default value of 1, this ensures # that we test a multiple page result when calling # comment_client.User.subscribed_threads() subscribed_thread_ids = [non_matching_id, self.discussion_id] else: subscribed_thread_ids = [] self.mock_request.side_effect = make_mock_responder( subscribed_thread_ids=subscribed_thread_ids, comment_data=self.comment, thread_data=self.thread, ) user = mock.Mock() comment = cc.Comment.find(id=self.comment['id']).retrieve() site = Site.objects.get_current() site_config = SiteConfigurationFactory.create(site=site) site_config.site_values[ENABLE_FORUM_NOTIFICATIONS_FOR_SITE_KEY] = True site_config.save() with mock.patch( 'lms.djangoapps.discussion.signals.handlers.get_current_site', return_value=site): comment_created.send(sender=None, user=user, post=comment) if user_subscribed: expected_message_context = get_base_template_context(site) expected_message_context.update({ 'comment_author_id': self.comment_author.id, 'comment_body': self.comment['body'], 'comment_created_at': ONE_HOUR_AGO, 'comment_id': self.comment['id'], 'comment_username': self.comment_author.username, 'course_id': self.course.id, 'thread_author_id': self.thread_author.id, 'thread_created_at': TWO_HOURS_AGO, 'thread_id': self.discussion_id, 'thread_title': 'thread-title', 'thread_username': self.thread_author.username, 'thread_commentable_id': self.thread['commentable_id'], 'post_link': 'https://{}{}'.format(site.domain, self.mock_permalink.return_value), 'site': site, 'site_id': site.id }) expected_recipient = Recipient(self.thread_author.username, self.thread_author.email) actual_message = self.mock_ace_send.call_args_list[0][0][0] assert expected_message_context == actual_message.context assert expected_recipient == actual_message.recipient assert self.course.language == actual_message.language self._assert_rendered_email(actual_message) else: assert not self.mock_ace_send.called
def setUp(self): # lint-amnesty, pylint: disable=super-method-not-called self.command = SendEmailBaseCommand() self.site = SiteFactory() self.site_config = SiteConfigurationFactory.create(site=self.site)
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.UPGRADE_REMINDER_NUM_BINS) user2 = UserFactory.create(id=tasks.UPGRADE_REMINDER_NUM_BINS * 2) ScheduleFactory.create( upgrade_deadline=datetime.datetime(2017, 8, 3, 17, 44, 30, tzinfo=pytz.UTC), enrollment__course__org=filtered_org, enrollment__user=user1, ) ScheduleFactory.create( upgrade_deadline=datetime.datetime(2017, 8, 3, 17, 44, 30, tzinfo=pytz.UTC), enrollment__course__org=unfiltered_org, enrollment__user=user1, ) ScheduleFactory.create( upgrade_deadline=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.upgrade_reminder_schedule_bin( limited_config.site.id, target_day_str=test_time_str, day_offset=2, 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)
def test_get_value_for_org(self): """ Test that get_value_for_org returns correct value for any given key. """ # add SiteConfiguration to database SiteConfigurationFactory.create( site=self.site, values=self.test_config1, ) SiteConfigurationFactory.create( site=self.site2, values=self.test_config2, ) # Make sure entry is saved and retrieved correctly self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config1['course_org_filter'], "university"), self.test_config1['university'], ) self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config1['course_org_filter'], "platform_name"), self.test_config1['platform_name'], ) self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config1['course_org_filter'], "SITE_NAME"), self.test_config1['SITE_NAME'], ) self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config1['course_org_filter'], "css_overrides_file"), self.test_config1['css_overrides_file'], ) self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config1['course_org_filter'], "ENABLE_MKTG_SITE"), self.test_config1['ENABLE_MKTG_SITE'], ) # Make sure entry is saved and retrieved correctly self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config2['course_org_filter'], "university"), self.test_config2['university'], ) self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config2['course_org_filter'], "platform_name"), self.test_config2['platform_name'], ) self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config2['course_org_filter'], "SITE_NAME"), self.test_config2['SITE_NAME'], ) self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config2['course_org_filter'], "css_overrides_file"), self.test_config2['css_overrides_file'], ) self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config2['course_org_filter'], "ENABLE_MKTG_SITE"), self.test_config2['ENABLE_MKTG_SITE'], ) # Test that the default value is returned if the value for the given key is not found in the configuration self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config1['course_org_filter'], "non-existent", "dummy-default-value"), "dummy-default-value", ) # Test that the default value is returned if the value for the given key is not found in the configuration self.assertEqual( SiteConfiguration.get_value_for_org( self.test_config2['course_org_filter'], "non-existent", "dummy-default-value"), "dummy-default-value", ) # Test that the default value is returned if org is not found in the configuration self.assertEqual( SiteConfiguration.get_value_for_org("non-existent-org", "platform_name", "dummy-default-value"), "dummy-default-value", )
def test_caching_course(self): course = CourseOverviewFactory.create(org='test-org') site_cfg = SiteConfigurationFactory.create( site_values={'course_org_filter': course.org}) course_config = CourseDurationLimitConfig(course=course, enabled=True, enabled_as_of=datetime(2018, 1, 1, tzinfo=pytz.UTC)) # lint-amnesty, pylint: disable=line-too-long course_config.save() RequestCache.clear_all_namespaces() # Check that the org value is not retrieved from cache after save with self.assertNumQueries(2): assert CourseDurationLimitConfig.current( course_key=course.id).enabled RequestCache.clear_all_namespaces() # Check that the org value can be retrieved from cache after read with self.assertNumQueries(0): assert CourseDurationLimitConfig.current( course_key=course.id).enabled course_config.enabled = False course_config.save() RequestCache.clear_all_namespaces() # Check that the org value in cache was deleted on save with self.assertNumQueries(2): assert not CourseDurationLimitConfig.current( course_key=course.id).enabled global_config = CourseDurationLimitConfig(enabled=True, enabled_as_of=datetime( 2018, 1, 1, tzinfo=pytz.UTC)) global_config.save() RequestCache.clear_all_namespaces() # Check that the org value is not updated in cache by changing the global value with self.assertNumQueries(0): assert not CourseDurationLimitConfig.current( course_key=course.id).enabled site_config = CourseDurationLimitConfig(site=site_cfg.site, enabled=True, enabled_as_of=datetime(2018, 1, 1, tzinfo=pytz.UTC)) # lint-amnesty, pylint: disable=line-too-long site_config.save() RequestCache.clear_all_namespaces() # Check that the org value is not updated in cache by changing the site value with self.assertNumQueries(0): assert not CourseDurationLimitConfig.current( course_key=course.id).enabled org_config = CourseDurationLimitConfig(org=course.org, enabled=True, enabled_as_of=datetime(2018, 1, 1, tzinfo=pytz.UTC)) # lint-amnesty, pylint: disable=line-too-long org_config.save() RequestCache.clear_all_namespaces() # Check that the org value is not updated in cache by changing the site value with self.assertNumQueries(0): assert not CourseDurationLimitConfig.current( course_key=course.id).enabled
def test_config_overrides(self, global_setting, site_setting, org_setting, course_setting): """ Test that the stacked configuration overrides happen in the correct order and priority. This is tested by exhaustively setting each combination of contexts, and validating that only the lowest level context that is set to not-None is applied. """ # Add a bunch of configuration outside the contexts that are being tested, to make sure # there are no leaks of configuration across contexts non_test_course_enabled = CourseOverviewFactory.create( org='non-test-org-enabled') non_test_course_disabled = CourseOverviewFactory.create( org='non-test-org-disabled') non_test_site_cfg_enabled = SiteConfigurationFactory.create( site_values={'course_org_filter': non_test_course_enabled.org}) non_test_site_cfg_disabled = SiteConfigurationFactory.create( site_values={'course_org_filter': non_test_course_disabled.org}) ContentTypeGatingConfig.objects.create(course=non_test_course_enabled, enabled=True, enabled_as_of=datetime( 2018, 1, 1)) ContentTypeGatingConfig.objects.create(course=non_test_course_disabled, enabled=False) ContentTypeGatingConfig.objects.create(org=non_test_course_enabled.org, enabled=True, enabled_as_of=datetime( 2018, 1, 1)) ContentTypeGatingConfig.objects.create( org=non_test_course_disabled.org, enabled=False) ContentTypeGatingConfig.objects.create( site=non_test_site_cfg_enabled.site, enabled=True, enabled_as_of=datetime(2018, 1, 1)) ContentTypeGatingConfig.objects.create( site=non_test_site_cfg_disabled.site, enabled=False) # Set up test objects test_course = CourseOverviewFactory.create(org='test-org') test_site_cfg = SiteConfigurationFactory.create( site_values={'course_org_filter': test_course.org}) ContentTypeGatingConfig.objects.create(enabled=global_setting, enabled_as_of=datetime( 2018, 1, 1)) ContentTypeGatingConfig.objects.create(course=test_course, enabled=course_setting, enabled_as_of=datetime( 2018, 1, 1)) ContentTypeGatingConfig.objects.create(org=test_course.org, enabled=org_setting, enabled_as_of=datetime( 2018, 1, 1)) ContentTypeGatingConfig.objects.create(site=test_site_cfg.site, enabled=site_setting, enabled_as_of=datetime( 2018, 1, 1)) all_settings = [ global_setting, site_setting, org_setting, course_setting ] expected_global_setting = self._resolve_settings([global_setting]) expected_site_setting = self._resolve_settings( [global_setting, site_setting]) expected_org_setting = self._resolve_settings( [global_setting, site_setting, org_setting]) expected_course_setting = self._resolve_settings( [global_setting, site_setting, org_setting, course_setting]) assert expected_global_setting == ContentTypeGatingConfig.current( ).enabled assert expected_site_setting == ContentTypeGatingConfig.current( site=test_site_cfg.site).enabled assert expected_org_setting == ContentTypeGatingConfig.current( org=test_course.org).enabled assert expected_course_setting == ContentTypeGatingConfig.current( course_key=test_course.id).enabled
def test_site_config_override(self): site_config = SiteConfigurationFactory.create(values=dict( GOOGLE_ANALYTICS_ACCOUNT='UA-654321-1')) pixel = GoogleAnalyticsTrackingPixel(site=site_config.site) self.assert_query_string_parameters_equal(pixel.generate_image_url(), tid='UA-654321-1')