Merge pull request #23224 from edx/revert-23214-pwnage101/rename_site_configuration_siteconfiguration_values_2.1

Revert "Rename values in SiteConfiguration (2/3) attempt #2"
This commit is contained in:
Troy Sankey
2020-02-27 13:58:53 -05:00
committed by GitHub
33 changed files with 176 additions and 184 deletions

View File

@@ -465,7 +465,7 @@ class AllowedAuthUserForm(forms.ModelForm):
if not allowed_site_email_domain:
raise forms.ValidationError(
_("Please add a key/value 'THIRD_PARTY_AUTH_ONLY_DOMAIN/{site_email_domain}' in SiteConfiguration "
"model's site_values field.")
"model's values field.")
)
elif email_domain != allowed_site_email_domain:
raise forms.ValidationError(

View File

@@ -454,7 +454,7 @@ class AllowedAuthUserFormTest(SiteMixin, TestCase):
def _update_site_configuration(self):
""" Updates the site's configuration """
self.site.configuration.site_values = {'THIRD_PARTY_AUTH_ONLY_DOMAIN': self.email_domain_name}
self.site.configuration.values = {'THIRD_PARTY_AUTH_ONLY_DOMAIN': self.email_domain_name}
self.site.configuration.save()
def _assert_form(self, site, email, is_valid_form=False):
@@ -480,7 +480,7 @@ class AllowedAuthUserFormTest(SiteMixin, TestCase):
self.assertEqual(
error,
"Please add a key/value 'THIRD_PARTY_AUTH_ONLY_DOMAIN/{site_email_domain}' in SiteConfiguration "
"model's site_values field."
"model's values field."
)
def test_form_with_invalid_domain_name(self):

View File

@@ -222,9 +222,7 @@ class MigrationTests(TestCase):
Tests for migrations.
"""
@unittest.skip(
"Need to skip as part of renaming a field in schedules app. This will be unskipped in DE-1825. ALSO need to skip as part of renaming a field in the site_configuration app. This will be unskipped in DENG-18."
)
@unittest.skip("Need to skip as part of renaming a field in schedules app. This will be unskipped in DE-1825")
@override_settings(MIGRATION_MODULES={})
def test_migrations_are_in_sync(self):
"""
@@ -239,6 +237,6 @@ class MigrationTests(TestCase):
release afterwards, this test doesn't fail.
"""
out = StringIO()
call_command("makemigrations", dry_run=True, verbosity=3, stdout=out)
call_command('makemigrations', dry_run=True, verbosity=3, stdout=out)
output = out.getvalue()
self.assertIn("No changes detected", output)
self.assertIn('No changes detected', output)

View File

@@ -297,7 +297,7 @@ class TestIndex(SiteMixin, TestCase):
response = self.client.get(reverse("root"))
self.assertRedirects(
response,
self.site_configuration_other.site_values["MKTG_URLS"]["ROOT"],
self.site_configuration_other.values["MKTG_URLS"]["ROOT"],
fetch_redirect_response=False
)
@@ -309,4 +309,4 @@ class TestIndex(SiteMixin, TestCase):
self.use_site(self.site_other)
self.client.login(username=self.user.username, password="password")
response = self.client.get(reverse("dashboard"))
self.assertIn(self.site_configuration_other.site_values["MKTG_URLS"]["ROOT"], response.content.decode('utf-8'))
self.assertIn(self.site_configuration_other.values["MKTG_URLS"]["ROOT"], response.content.decode('utf-8'))

View File

@@ -30,6 +30,7 @@ class SendMessageHandlerTestCase(TestCase):
site_config = SiteConfigurationFactory.create(site=self.site)
enable_notifications_cfg = {ENABLE_FORUM_NOTIFICATIONS_FOR_SITE_KEY: True}
site_config.site_values = enable_notifications_cfg
site_config.values = enable_notifications_cfg
site_config.save()
mock_get_current_site.return_value = self.site
signals.comment_created.send(sender=self.sender, user=self.user, post=self.post)
@@ -59,6 +60,7 @@ class SendMessageHandlerTestCase(TestCase):
site_config = SiteConfigurationFactory.create(site=self.site)
enable_notifications_cfg = {ENABLE_FORUM_NOTIFICATIONS_FOR_SITE_KEY: False}
site_config.site_values = enable_notifications_cfg
site_config.values = enable_notifications_cfg
site_config.save()
mock_get_current_site.return_value = self.site
signals.comment_created.send(sender=self.sender, user=self.user, post=self.post)

View File

@@ -193,7 +193,7 @@ class TaskTestCase(ModuleStoreTestCase):
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.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)

View File

@@ -4000,8 +4000,8 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
self.assertEqual(response.status_code, 400)
def test_send_email_with_site_template_and_from_addr(self):
site_email = self.site_configuration.site_values.get('course_email_from_addr')
site_template = self.site_configuration.site_values.get('course_email_template_name')
site_email = self.site_configuration.values.get('course_email_from_addr')
site_template = self.site_configuration.values.get('course_email_template_name')
CourseEmailTemplate.objects.create(name=site_template)
url = reverse('send_email', kwargs={'course_id': text_type(self.course.id)})
response = self.client.post(url, self.full_test_message)
@@ -4019,7 +4019,7 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
org_email = 'fake_org@example.com'
org_template = 'fake_org_email_template'
CourseEmailTemplate.objects.create(name=org_template)
self.site_configuration.site_values.update({
self.site_configuration.values.update({
'course_email_from_addr': {self.course.id.org: org_email},
'course_email_template_name': {self.course.id.org: org_template}
})

View File

@@ -169,6 +169,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
SiteConfiguration.objects.create(
site=site,
site_values=configuration_values,
values=configuration_values,
enabled=True
)
@@ -201,6 +202,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
SiteConfiguration.objects.create(
site=site,
site_values=configuration_values,
values=configuration_values,
enabled=True
)
url = reverse(

View File

@@ -124,6 +124,9 @@ class TestGoogleAnalyticsTrackingPixel(QueryStringAssertionMixin, CacheIsolation
site_config = SiteConfigurationFactory.create(
site_values=dict(
GOOGLE_ANALYTICS_ACCOUNT='UA-654321-1'
),
values=dict(
GOOGLE_ANALYTICS_ACCOUNT='UA-654321-1'
)
)
pixel = GoogleAnalyticsTrackingPixel(site=site_config.site)

View File

@@ -27,7 +27,8 @@ def cache_programs(request):
SiteConfiguration.objects.create(
site=request.site,
enabled=True,
site_values={"COURSE_CATALOG_API_URL": "{catalog_url}/api/v1/".format(catalog_url=CATALOG_STUB_URL)}
site_values={"COURSE_CATALOG_API_URL": "{catalog_url}/api/v1/".format(catalog_url=CATALOG_STUB_URL)},
values={"COURSE_CATALOG_API_URL": "{catalog_url}/api/v1/".format(catalog_url=CATALOG_STUB_URL)}
)
if settings.FEATURES.get('EXPOSE_CACHE_PROGRAMS_ENDPOINT'):

View File

@@ -244,7 +244,7 @@ class StackedConfigurationModel(ConfigurationModel):
"""
all_courses = CourseOverview.objects.all()
all_site_configs = SiteConfiguration.objects.filter(
site_values__contains='course_org_filter', enabled=True
values__contains='course_org_filter', enabled=True
).select_related('site')
try:
@@ -254,7 +254,7 @@ class StackedConfigurationModel(ConfigurationModel):
sites_by_org = defaultdict(lambda: default_site)
site_cfg_org_filters = (
(site_cfg.site, site_cfg.site_values['course_org_filter'])
(site_cfg.site, site_cfg.values['course_org_filter'])
for site_cfg in all_site_configs
)
sites_by_org.update({

View File

@@ -157,7 +157,8 @@ class TestNotifyCredentials(TestCase):
@mock.patch(COMMAND_MODULE + '.handle_cert_change')
def test_site(self, mock_grade_interesting, mock_cert_change):
site_config = SiteConfigurationFactory.create(
site_values={'course_org_filter': ['testX']}
site_values={'course_org_filter': ['testX']},
values={'course_org_filter': ['testX']},
)
call_command(Command(), '--site', site_config.site.domain, '--start-date', '2017-01-01')

View File

@@ -110,7 +110,8 @@ class TestCredentialsSignalsSendGrade(TestCase):
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(
site_values={'course_org_filter': [self.key.org]}
site_values={'course_org_filter': [self.key.org]},
values={'course_org_filter': [self.key.org]},
)
# Correctly sent
@@ -119,7 +120,7 @@ class TestCredentialsSignalsSendGrade(TestCase):
mock_send_grade_to_credentials.delay.reset_mock()
# Correctly not sent
site_config.site_values['ENABLE_LEARNER_RECORDS'] = False
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)

View File

@@ -196,7 +196,7 @@ class AwardProgramCertificatesTestCase(CatalogIntegrationMixin, CredentialsApiCo
mock_get_certified_programs.return_value = [1]
# programs to be skipped
self.site_configuration.site_values = {
self.site_configuration.values = {
"programs_without_certificates": [2]
}
self.site_configuration.save()

View File

@@ -146,7 +146,8 @@ class CertChangedReceiverTest(TestCase):
mock_is_learner_issuance_enabled.return_value = True
site_config = SiteConfigurationFactory.create(
site_values={'course_org_filter': ['edX']}
site_values={'course_org_filter': ['edX']},
values={'course_org_filter': ['edX']},
)
# Correctly sent
@@ -155,7 +156,7 @@ class CertChangedReceiverTest(TestCase):
mock_task.reset_mock()
# Correctly not sent
site_config.site_values['ENABLE_LEARNER_RECORDS'] = False
site_config.values['ENABLE_LEARNER_RECORDS'] = False
site_config.save()
handle_course_cert_changed(**self.signal_kwargs)
self.assertFalse(mock_task.called)

View File

@@ -308,10 +308,12 @@ class ScheduleSendEmailTestMixin(FilteredQueryCountMixin):
filtered_org = 'filtered_org'
unfiltered_org = 'unfiltered_org'
this_config = SiteConfigurationFactory.create(
site_values={'course_org_filter': this_org_list}
site_values={'course_org_filter': this_org_list},
values={'course_org_filter': this_org_list}
)
other_config = SiteConfigurationFactory.create(
site_values={'course_org_filter': other_org_list}
site_values={'course_org_filter': other_org_list},
values={'course_org_filter': other_org_list}
)
for config in (this_config, other_config):

View File

@@ -61,7 +61,7 @@ class TestBinnedSchedulesBaseResolver(SchedulesResolverTestMixin, TestCase):
'course1'
)
def test_get_course_org_filter_equal(self, course_org_filter):
self.site_config.site_values['course_org_filter'] = course_org_filter
self.site_config.values['course_org_filter'] = course_org_filter
self.site_config.save()
mock_query = Mock()
result = self.resolver.filter_by_org(mock_query)
@@ -73,7 +73,7 @@ class TestBinnedSchedulesBaseResolver(SchedulesResolverTestMixin, TestCase):
(['course1', 'course2'], ['course1', 'course2'])
)
def test_get_course_org_filter_include__in(self, course_org_filter, expected_org_list):
self.site_config.site_values['course_org_filter'] = course_org_filter
self.site_config.values['course_org_filter'] = course_org_filter
self.site_config.save()
mock_query = Mock()
result = self.resolver.filter_by_org(mock_query)
@@ -88,7 +88,8 @@ class TestBinnedSchedulesBaseResolver(SchedulesResolverTestMixin, TestCase):
)
def test_get_course_org_filter_exclude__in(self, course_org_filter, expected_org_list):
SiteConfigurationFactory.create(
site_values={'course_org_filter': course_org_filter}
site_values={'course_org_filter': course_org_filter},
values={'course_org_filter': course_org_filter},
)
mock_query = Mock()
result = self.resolver.filter_by_org(mock_query)

View File

@@ -12,8 +12,8 @@ class SiteConfigurationAdmin(admin.ModelAdmin):
"""
Admin interface for the SiteConfiguration object.
"""
list_display = ('site', 'enabled', 'site_values')
search_fields = ('site__domain', 'site_values')
list_display = ('site', 'enabled', 'values')
search_fields = ('site__domain', 'values')
class Meta(object):
"""
@@ -29,7 +29,7 @@ class SiteConfigurationHistoryAdmin(admin.ModelAdmin):
Admin interface for the SiteConfigurationHistory object.
"""
list_display = ('site', 'enabled', 'created', 'modified')
search_fields = ('site__domain', 'site_values', 'created', 'modified')
search_fields = ('site__domain', 'values', 'created', 'modified')
ordering = ['-created']

View File

@@ -53,7 +53,7 @@ def has_configuration_override(name):
(bool): True if given key is present in the configuration.
"""
configuration = get_current_site_configuration()
if configuration and name in configuration.site_values:
if configuration and name in configuration.values:
return True
return False

View File

@@ -103,6 +103,10 @@ class Command(BaseCommand):
site_configuration_values = configuration or config_file_data
if site_configuration_values:
if site_configuration.values:
site_configuration.values.update(site_configuration_values)
else:
site_configuration.values = site_configuration_values
if site_configuration.site_values:
site_configuration.site_values.update(site_configuration_values)
else:

View File

@@ -56,7 +56,7 @@ class CreateOrUpdateSiteConfigurationTest(TestCase):
def create_fixture_site_configuration(self, enabled):
SiteConfiguration.objects.update_or_create(
site=self.site,
defaults={'enabled': enabled, 'site_values': {'ABC': 'abc', 'B': 'b'}}
defaults={'enabled': enabled, 'values': {'ABC': 'abc', 'B': 'b'}}
)
def test_command_no_args(self):
@@ -105,7 +105,7 @@ class CreateOrUpdateSiteConfigurationTest(TestCase):
call_command(self.command, *self.site_id_arg)
site_configuration = SiteConfiguration.objects.get(site=self.site)
self.assertFalse(site_configuration.site_values)
self.assertFalse(site_configuration.values)
self.assertFalse(site_configuration.enabled)
def test_both_enabled_disabled_flags(self):
@@ -126,7 +126,7 @@ class CreateOrUpdateSiteConfigurationTest(TestCase):
self.assert_site_configuration_does_not_exist()
call_command(self.command, '--{}'.format(flag), *self.site_id_arg)
site_configuration = SiteConfiguration.objects.get(site=self.site)
self.assertFalse(site_configuration.site_values)
self.assertFalse(site_configuration.values)
self.assertEqual(enabled, site_configuration.enabled)
def test_site_configuration_created_with_parameters(self):
@@ -136,7 +136,7 @@ class CreateOrUpdateSiteConfigurationTest(TestCase):
self.assert_site_configuration_does_not_exist()
call_command(self.command, '--configuration', json.dumps(self.input_configuration), *self.site_id_arg)
site_configuration = self.get_site_configuration()
self.assertDictEqual(site_configuration.site_values, self.input_configuration)
self.assertDictEqual(site_configuration.values, self.input_configuration)
def test_site_configuration_created_with_json_file_parameters(self):
"""
@@ -145,7 +145,7 @@ class CreateOrUpdateSiteConfigurationTest(TestCase):
self.assert_site_configuration_does_not_exist()
call_command(self.command, '-f', str(self.json_file_path.abspath()), *self.site_id_arg)
site_configuration = self.get_site_configuration()
self.assertEqual(site_configuration.site_values, {'ABC': 123, 'XYZ': '789'})
self.assertEqual(site_configuration.values, {'ABC': 123, 'XYZ': '789'})
@ddt.data(True, False)
def test_site_configuration_updated_with_parameters(self, enabled):
@@ -156,7 +156,7 @@ class CreateOrUpdateSiteConfigurationTest(TestCase):
call_command(self.command, '--configuration', json.dumps(self.input_configuration), *self.site_id_arg)
site_configuration = self.get_site_configuration()
self.assertEqual(
site_configuration.site_values,
site_configuration.values,
{'ABC': 123, 'B': 'b', 'FEATURE_FLAG': True, 'SERVICE_URL': 'https://foo.bar'}
)
self.assertEqual(site_configuration.enabled, enabled)
@@ -172,5 +172,5 @@ class CreateOrUpdateSiteConfigurationTest(TestCase):
expected_site_configuration = {'ABC': 'abc', 'B': 'b'}
with codecs.open(self.json_file_path, encoding='utf-8') as f:
expected_site_configuration.update(json.load(f))
self.assertEqual(site_configuration.site_values, expected_site_configuration)
self.assertEqual(site_configuration.values, expected_site_configuration)
self.assertEqual(site_configuration.enabled, enabled)

View File

@@ -1,41 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.27 on 2020-01-03 20:57
from __future__ import unicode_literals
from django.db import migrations
from ..models import save_siteconfig_without_historical_record
def copy_column_values(apps, schema_editor):
"""
Copy the contents of the values field into the site_values field in both
SiteConfiguration and SiteConfigurationHistory.
"""
# Update all values in the model.
SiteConfiguration = apps.get_model('site_configuration', 'SiteConfiguration')
for site_configuration in SiteConfiguration.objects.all():
site_configuration.site_values = site_configuration.values
# It would be incorrect to record these saves in the history table since it is
# just backfilling data. Use save_without_historical_record() instead of
# save().
save_siteconfig_without_historical_record(site_configuration)
# Update all values in the history model.
SiteConfigurationHistory = apps.get_model('site_configuration', 'SiteConfigurationHistory')
for historical_site_configuration in SiteConfigurationHistory.objects.all():
historical_site_configuration.site_values = historical_site_configuration.values
historical_site_configuration.save()
class Migration(migrations.Migration):
dependencies = [
('site_configuration', '0004_add_site_values_field'),
]
operations = [
migrations.RunPython(
copy_column_values,
reverse_code=migrations.RunPython.noop, # Allow reverse migrations, but make it a no-op.
),
]

View File

@@ -40,6 +40,13 @@ class SiteConfiguration(models.Model):
default=dict,
load_kwargs={'object_pairs_hook': collections.OrderedDict}
)
# TODO: Delete this deprecated field during the later stages of the rollout
# which renames 'values' to 'site_values'.
values = JSONField(
null=False,
blank=True,
load_kwargs={'object_pairs_hook': collections.OrderedDict}
)
def __str__(self):
return u"<SiteConfiguration: {site} >".format(site=self.site) # xss-lint: disable=python-wrap-html
@@ -62,7 +69,7 @@ class SiteConfiguration(models.Model):
"""
if self.enabled:
try:
return self.site_values.get(name, default)
return self.values.get(name, default)
except AttributeError as error:
logger.exception(u'Invalid JSON data. \n [%s]', error)
else:
@@ -80,7 +87,7 @@ class SiteConfiguration(models.Model):
org (str): Org to use to filter SiteConfigurations
select_related (list or None): A list of values to pass as arguments to select_related
"""
query = cls.objects.filter(site_values__contains=org, enabled=True).all()
query = cls.objects.filter(values__contains=org, enabled=True).all()
if select_related is not None:
query = query.select_related(*select_related)
for configuration in query:
@@ -124,7 +131,7 @@ class SiteConfiguration(models.Model):
"""
org_filter_set = set()
for configuration in cls.objects.filter(site_values__contains='course_org_filter', enabled=True).all():
for configuration in cls.objects.filter(values__contains='course_org_filter', enabled=True).all():
course_org_filter = configuration.get_value('course_org_filter', [])
if not isinstance(course_org_filter, list):
course_org_filter = [course_org_filter]
@@ -142,22 +149,6 @@ class SiteConfiguration(models.Model):
return org in cls.get_all_orgs()
def save_siteconfig_without_historical_record(siteconfig, *args, **kwargs):
"""
Save model without saving a historical record
Make sure you know what you're doing before you use this method.
Note: this method is copied verbatim from django-simple-history.
"""
siteconfig.skip_history_when_saving = True
try:
ret = siteconfig.save(*args, **kwargs)
finally:
del siteconfig.skip_history_when_saving
return ret
@python_2_unicode_compatible
class SiteConfigurationHistory(TimeStampedModel):
"""
@@ -177,6 +168,13 @@ class SiteConfigurationHistory(TimeStampedModel):
blank=True,
load_kwargs={'object_pairs_hook': collections.OrderedDict}
)
# TODO: Delete this deprecated field during the later stages of the rollout
# which renames 'values' to 'site_values'.
values = JSONField(
null=False,
blank=True,
load_kwargs={'object_pairs_hook': collections.OrderedDict}
)
class Meta:
get_latest_by = 'modified'
@@ -194,27 +192,18 @@ class SiteConfigurationHistory(TimeStampedModel):
@receiver(post_save, sender=SiteConfiguration)
def update_site_configuration_history(sender, instance, created, **kwargs): # pylint: disable=unused-argument
def update_site_configuration_history(sender, instance, **kwargs): # pylint: disable=unused-argument
"""
Add site configuration changes to site configuration history.
Recording history on updates and deletes can be skipped by first setting
the `skip_history_when_saving` attribute on the instace, e.g.:
site_config.skip_history_when_saving = True
site_config.save()
Args:
sender: sender of the signal i.e. SiteConfiguration model
instance: SiteConfiguration instance associated with the current signal
created (bool): True if a new record was created.
**kwargs: extra key word arguments
"""
# Skip writing history when asked by the caller. This skip feature only
# works for non-creates.
if created or not hasattr(instance, "skip_history_when_saving"):
SiteConfigurationHistory.objects.create(
site=instance.site,
site_values=instance.site_values,
enabled=instance.enabled,
)
SiteConfigurationHistory.objects.create(
site=instance.site,
site_values=instance.values,
values=instance.values,
enabled=instance.enabled,
)

View File

@@ -33,5 +33,5 @@ class SiteConfigurationFactory(DjangoModelFactory):
site = SubFactory(SiteFactory)
@lazy_attribute
def site_values(self):
def values(self):
return {}

View File

@@ -22,7 +22,9 @@ class SiteMixin(object):
}
self.site_configuration = SiteConfigurationFactory.create(
site=self.site,
site_values=site_config
site_values=site_config,
# TODO: Remove this deprecated value eventually.
values=site_config
)
self.site_other = SiteFactory.create(
@@ -42,7 +44,9 @@ class SiteMixin(object):
}
self.site_configuration_other = SiteConfigurationFactory.create(
site=self.site_other,
site_values=site_config_other
site_values=site_config_other,
# TODO: Remove this deprecated value eventually.
values=site_config_other
)
# Initialize client with default site domain
@@ -58,7 +62,9 @@ class SiteMixin(object):
)
__ = SiteConfigurationFactory.create(
site=site,
site_values=site_configuration_values
site_values=site_configuration_values,
# TODO: Remove this deprecated value eventually.
values=site_configuration_values
)
self.use_site(site)
return site

View File

@@ -40,6 +40,9 @@ class SessionCookieDomainTests(TestCase):
site=self.site,
site_values={
"SESSION_COOKIE_DOMAIN": self.site.domain,
},
values={
"SESSION_COOKIE_DOMAIN": self.site.domain,
}
)
@@ -75,6 +78,9 @@ class SessionCookieDomainSiteConfigurationOverrideTests(TestCase):
site=self.site,
site_values={
"SESSION_COOKIE_DOMAIN": self.site.domain,
},
values={
"SESSION_COOKIE_DOMAIN": self.site.domain,
}
)
self.client = Client()

View File

@@ -1,17 +1,16 @@
"""
Tests for site configuration's django models.
"""
from mock import patch
import six
from django.contrib.sites.models import Site
from django.db import IntegrityError, transaction
from django.test import TestCase
from mock import patch
from openedx.core.djangoapps.site_configuration.models import (
SiteConfiguration,
SiteConfigurationHistory,
save_siteconfig_without_historical_record
)
from django.db import IntegrityError, transaction
from django.contrib.sites.models import Site
from openedx.core.djangoapps.site_configuration.models import SiteConfigurationHistory, SiteConfiguration
from openedx.core.djangoapps.site_configuration.tests.factories import SiteConfigurationFactory
@@ -84,6 +83,8 @@ class SiteConfigurationTests(TestCase):
)
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.
@@ -91,33 +92,9 @@ class SiteConfigurationTests(TestCase):
site=site_configuration.site,
).all()
# Make sure two entries (one for create and one for update) are saved for SiteConfiguration
# Make sure two entries (one for save and one for update) are saved for SiteConfiguration
self.assertEqual(len(site_configuration_history), 2)
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_no_entry_is_saved_for_errors(self):
"""
Test that and entry is not added to SiteConfigurationHistory if there is an error while
@@ -156,7 +133,9 @@ class SiteConfigurationTests(TestCase):
# add SiteConfiguration to database
site_configuration = SiteConfigurationFactory.create(
site=self.site,
site_values=self.test_config1
site_values=self.test_config1,
# TODO: Remove this deprecated value eventually.
values=self.test_config1,
)
# Make sure entry is saved and retrieved correctly
@@ -204,7 +183,9 @@ class SiteConfigurationTests(TestCase):
# add SiteConfiguration to database
site_configuration = SiteConfigurationFactory.create(
site=self.site,
site_values=invalid_data
site_values=invalid_data,
# TODO: Remove this deprecated value eventually.
values=invalid_data,
)
# make sure get_value logs an error for invalid json data
@@ -225,11 +206,15 @@ class SiteConfigurationTests(TestCase):
# add SiteConfiguration to database
SiteConfigurationFactory.create(
site=self.site,
site_values=self.test_config1
site_values=self.test_config1,
# TODO: Remove this deprecated value eventually.
values=self.test_config1,
)
SiteConfigurationFactory.create(
site=self.site2,
site_values=self.test_config2
site_values=self.test_config2,
# TODO: Remove this deprecated value eventually.
values=self.test_config2,
)
# Make sure entry is saved and retrieved correctly
@@ -310,11 +295,15 @@ class SiteConfigurationTests(TestCase):
# add SiteConfiguration to database
config1 = SiteConfigurationFactory.create(
site=self.site,
site_values=self.test_config1
site_values=self.test_config1,
# TODO: Remove this deprecated value eventually.
values=self.test_config1,
)
config2 = SiteConfigurationFactory.create(
site=self.site2,
site_values=self.test_config2
site_values=self.test_config2,
# TODO: Remove this deprecated value eventually.
values=self.test_config2,
)
# Make sure entry is saved and retrieved correctly
@@ -339,11 +328,15 @@ class SiteConfigurationTests(TestCase):
# add SiteConfiguration to database
SiteConfigurationFactory.create(
site=self.site,
site_values=self.test_config1
site_values=self.test_config1,
# TODO: Remove this deprecated value eventually.
values=self.test_config1,
)
SiteConfigurationFactory.create(
site=self.site2,
site_values=self.test_config2
site_values=self.test_config2,
# TODO: Remove this deprecated value eventually.
values=self.test_config2,
)
# Test that the default value is returned if the value for the given key is not found in the configuration
@@ -358,11 +351,15 @@ class SiteConfigurationTests(TestCase):
SiteConfigurationFactory.create(
site=self.site,
site_values=self.test_config1,
# TODO: Remove this deprecated value eventually.
values=self.test_config1,
enabled=False,
)
SiteConfigurationFactory.create(
site=self.site2,
site_values=self.test_config2
site_values=self.test_config2,
# TODO: Remove this deprecated value eventually.
values=self.test_config2,
)
# Test that the default value is returned if the value for the given key is not found in the configuration

View File

@@ -29,10 +29,11 @@ def with_site_configuration(domain="test.localhost", configuration=None):
site, __ = Site.objects.get_or_create(domain=domain, name=domain)
site_configuration, created = SiteConfiguration.objects.get_or_create(
site=site,
defaults={"enabled": True, "site_values": configuration},
defaults={"enabled": True, "site_values": configuration, "values": configuration},
)
if not created:
site_configuration.site_values = configuration
site_configuration.values = configuration
site_configuration.save()
with patch('openedx.core.djangoapps.site_configuration.helpers.get_current_site_configuration',
@@ -56,10 +57,11 @@ def with_site_configuration_context(domain="test.localhost", configuration=None)
site, __ = Site.objects.get_or_create(domain=domain, name=domain)
site_configuration, created = SiteConfiguration.objects.get_or_create(
site=site,
defaults={"enabled": True, "site_values": configuration},
defaults={"enabled": True, "site_values": configuration, "values": configuration},
)
if not created:
site_configuration.site_values = configuration
site_configuration.values = configuration
site_configuration.save()
with patch('openedx.core.djangoapps.site_configuration.helpers.get_current_site_configuration',

View File

@@ -116,6 +116,7 @@ class Command(BaseCommand):
SiteConfiguration.objects.create(
site=site,
site_values=site_configuration,
values=site_configuration,
enabled=True
)
else:

View File

@@ -31,7 +31,8 @@ class TestHubspotSyncCommand(TestCase):
super(TestHubspotSyncCommand, cls).setUpClass()
cls.site_config = SiteConfigurationFactory()
cls.hubspot_site_config = SiteConfigurationFactory.create(
site_values={'HUBSPOT_API_KEY': 'test_key'}
site_values={'HUBSPOT_API_KEY': 'test_key'},
values={'HUBSPOT_API_KEY': 'test_key'},
)
cls.users = []
cls._create_users(cls.hubspot_site_config) # users for a site with hubspot integration enabled
@@ -63,8 +64,8 @@ class TestHubspotSyncCommand(TestCase):
"""
Test no _sync_site call is made if hubspot integration is not enabled for any site
"""
orig_values = self.hubspot_site_config.site_values
self.hubspot_site_config.site_values = {}
orig_values = self.hubspot_site_config.values
self.hubspot_site_config.values = {}
self.hubspot_site_config.save()
sync_site = patch.object(sync_command, '_sync_site')
mock_sync_site = sync_site.start()
@@ -72,7 +73,7 @@ class TestHubspotSyncCommand(TestCase):
self.assertFalse(mock_sync_site.called, "_sync_site should not be called")
sync_site.stop()
# put values back
self.hubspot_site_config.site_values = orig_values
self.hubspot_site_config.values = orig_values
self.hubspot_site_config.save()
def test_with_initial_sync_days(self):

View File

@@ -132,10 +132,12 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
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}
site_values={'course_org_filter': non_test_course_enabled.org},
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}
site_values={'course_org_filter': non_test_course_disabled.org},
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))
@@ -148,7 +150,8 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
# Set up test objects
test_course = CourseOverviewFactory.create(org='test-org')
test_site_cfg = SiteConfigurationFactory.create(
site_values={'course_org_filter': test_course.org}
site_values={'course_org_filter': test_course.org},
values={'course_org_filter': test_course.org}
)
ContentTypeGatingConfig.objects.create(enabled=global_setting, enabled_as_of=datetime(2018, 1, 1))
@@ -173,13 +176,14 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
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': []}
site_values={'course_org_filter': []},
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.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))
@@ -288,7 +292,8 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
def test_caching_org(self):
course = CourseOverviewFactory.create(org='test-org')
site_cfg = SiteConfigurationFactory.create(
site_values={'course_org_filter': course.org}
site_values={'course_org_filter': course.org},
values={'course_org_filter': course.org}
)
org_config = ContentTypeGatingConfig(org=course.org, enabled=True, enabled_as_of=datetime(2018, 1, 1))
org_config.save()
@@ -335,7 +340,8 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
def test_caching_course(self):
course = CourseOverviewFactory.create(org='test-org')
site_cfg = SiteConfigurationFactory.create(
site_values={'course_org_filter': course.org}
site_values={'course_org_filter': course.org},
values={'course_org_filter': course.org}
)
course_config = ContentTypeGatingConfig(course=course, enabled=True, enabled_as_of=datetime(2018, 1, 1))
course_config.save()

View File

@@ -142,10 +142,12 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase):
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}
site_values={'course_org_filter': non_test_course_enabled.org},
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}
site_values={'course_org_filter': non_test_course_disabled.org},
values={'course_org_filter': non_test_course_disabled.org}
)
CourseDurationLimitConfig.objects.create(course=non_test_course_enabled, enabled=True)
@@ -158,7 +160,8 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase):
# Set up test objects
test_course = CourseOverviewFactory.create(org='test-org')
test_site_cfg = SiteConfigurationFactory.create(
site_values={'course_org_filter': test_course.org}
site_values={'course_org_filter': test_course.org},
values={'course_org_filter': test_course.org}
)
if reverse_order:
@@ -188,7 +191,8 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase):
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(
site_values={'course_org_filter': []}
site_values={'course_org_filter': []},
values={'course_org_filter': []}
)
CourseDurationLimitConfig.objects.create(
site=test_site_cfg.site, enabled=site_setting, enabled_as_of=datetime(2018, 1, 1)
@@ -196,7 +200,7 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase):
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.values['course_org_filter'].append(test_org)
test_site_cfg.save()
CourseDurationLimitConfig.objects.create(
@@ -306,7 +310,8 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase):
def test_caching_org(self):
course = CourseOverviewFactory.create(org='test-org')
site_cfg = SiteConfigurationFactory.create(
site_values={'course_org_filter': course.org}
site_values={'course_org_filter': course.org},
values={'course_org_filter': course.org}
)
org_config = CourseDurationLimitConfig(org=course.org, enabled=True, enabled_as_of=datetime(2018, 1, 1))
org_config.save()
@@ -353,7 +358,8 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase):
def test_caching_course(self):
course = CourseOverviewFactory.create(org='test-org')
site_cfg = SiteConfigurationFactory.create(
site_values={'course_org_filter': course.org}
site_values={'course_org_filter': course.org},
values={'course_org_filter': course.org}
)
course_config = CourseDurationLimitConfig(course=course, enabled=True, enabled_as_of=datetime(2018, 1, 1))
course_config.save()

View File

@@ -59,10 +59,12 @@ class TestDiscountRestrictionConfig(CacheIsolationTestCase):
non_test_course_disabled = CourseOverviewFactory.create(org='non-test-org-disabled')
non_test_course_enabled = CourseOverviewFactory.create(org='non-test-org-enabled')
non_test_site_cfg_disabled = SiteConfigurationFactory.create(
site_values={'course_org_filter': non_test_course_disabled.org}
site_values={'course_org_filter': non_test_course_disabled.org},
values={'course_org_filter': non_test_course_disabled.org}
)
non_test_site_cfg_enabled = SiteConfigurationFactory.create(
site_values={'course_org_filter': non_test_course_enabled.org}
site_values={'course_org_filter': non_test_course_enabled.org},
values={'course_org_filter': non_test_course_enabled.org}
)
DiscountRestrictionConfig.objects.create(course=non_test_course_disabled, disabled=True)
@@ -75,7 +77,8 @@ class TestDiscountRestrictionConfig(CacheIsolationTestCase):
# Set up test objects
test_course = CourseOverviewFactory.create(org='test-org')
test_site_cfg = SiteConfigurationFactory.create(
site_values={'course_org_filter': test_course.org}
site_values={'course_org_filter': test_course.org},
values={'course_org_filter': test_course.org}
)
DiscountRestrictionConfig.objects.create(disabled=global_setting)