Skip to content
Snippets Groups Projects
Commit 18deacde authored by Troy Sankey's avatar Troy Sankey
Browse files

Revert "Revert "This stage does the following: (#22692)""

This reverts commit 84de6bc6
which reverts commit cebeab43
which implements the first stage of the `values` column rename in
SiteConfiguration.  However, I included a small change:

This time, we set a default value on the new `site_values` column so
that the ORM will happily deserialize the JSONField without throwing a
JSONDecodeError.
parent 5e6d3a04
No related branches found
No related tags found
No related merge requests found
Showing
with 193 additions and 38 deletions
......@@ -28,7 +28,9 @@ class SendMessageHandlerTestCase(TestCase):
@mock.patch('lms.djangoapps.discussion.signals.handlers.send_message')
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
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)
......@@ -56,7 +58,9 @@ class SendMessageHandlerTestCase(TestCase):
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
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)
......
......@@ -166,7 +166,12 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
"ENABLE_MANUAL_ENROLLMENT_REASON_FIELD": enbale_reason_field
}
site = Site.objects.first()
SiteConfiguration.objects.create(site=site, values=configuration_values, enabled=True)
SiteConfiguration.objects.create(
site=site,
site_values=configuration_values,
values=configuration_values,
enabled=True
)
url = reverse(
'instructor_dashboard',
......@@ -194,7 +199,12 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
]
}
site = Site.objects.first()
SiteConfiguration.objects.create(site=site, values=configuration_values, enabled=True)
SiteConfiguration.objects.create(
site=site,
site_values=configuration_values,
values=configuration_values,
enabled=True
)
url = reverse(
'instructor_dashboard',
kwargs={
......
......@@ -122,6 +122,9 @@ class TestGoogleAnalyticsTrackingPixel(QueryStringAssertionMixin, CacheIsolation
@override_settings(GOOGLE_ANALYTICS_TRACKING_ID='UA-123456-1')
def test_site_config_override(self):
site_config = SiteConfigurationFactory.create(
site_values=dict(
GOOGLE_ANALYTICS_ACCOUNT='UA-654321-1'
),
values=dict(
GOOGLE_ANALYTICS_ACCOUNT='UA-654321-1'
)
......
......@@ -27,6 +27,7 @@ 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)},
values={"COURSE_CATALOG_API_URL": "{catalog_url}/api/v1/".format(catalog_url=CATALOG_STUB_URL)}
)
......
......@@ -157,6 +157,7 @@ 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']},
values={'course_org_filter': ['testX']},
)
......
......@@ -110,6 +110,7 @@ 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]},
values={'course_org_filter': [self.key.org]},
)
......
......@@ -146,6 +146,7 @@ class CertChangedReceiverTest(TestCase):
mock_is_learner_issuance_enabled.return_value = True
site_config = SiteConfigurationFactory.create(
site_values={'course_org_filter': ['edX']},
values={'course_org_filter': ['edX']},
)
......
......@@ -307,8 +307,14 @@ class ScheduleSendEmailTestMixin(FilteredQueryCountMixin):
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})
this_config = SiteConfigurationFactory.create(
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},
values={'course_org_filter': other_org_list}
)
for config in (this_config, other_config):
ScheduleConfigFactory.create(site=config.site)
......
......@@ -88,6 +88,7 @@ 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},
values={'course_org_filter': course_org_filter},
)
mock_query = Mock()
......
......@@ -107,6 +107,10 @@ class Command(BaseCommand):
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:
site_configuration.site_values = site_configuration_values
if enabled is not None:
site_configuration.enabled = enabled
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.28 on 2020-02-19 16:50
from __future__ import unicode_literals
import collections
from django.db import migrations
import jsonfield.encoder
import jsonfield.fields
class Migration(migrations.Migration):
dependencies = [
('site_configuration', '0003_auto_20200217_1058'),
]
operations = [
migrations.AddField(
model_name='siteconfiguration',
name='site_values',
field=jsonfield.fields.JSONField(blank=True, default=dict, dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={'object_pairs_hook': collections.OrderedDict}),
),
migrations.AddField(
model_name='siteconfigurationhistory',
name='site_values',
field=jsonfield.fields.JSONField(blank=True, dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={'object_pairs_hook': collections.OrderedDict}),
),
]
......@@ -25,12 +25,23 @@ class SiteConfiguration(models.Model):
Fields:
site (OneToOneField): one to one field relating each configuration to a single site
values (JSONField): json field to store configurations for a site
site_values (JSONField): json field to store configurations for a site
.. no_pii:
"""
site = models.OneToOneField(Site, related_name='configuration', on_delete=models.CASCADE)
enabled = models.BooleanField(default=False, verbose_name=u"Enabled")
site_values = JSONField(
null=False,
blank=True,
# The actual default value is determined by calling the given callable.
# Therefore, the default here is just {}, since that is the result of
# calling `dict`.
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,
......@@ -146,12 +157,19 @@ class SiteConfigurationHistory(TimeStampedModel):
Fields:
site (ForeignKey): foreign-key to django Site
values (JSONField): json field to store configurations for a site
site_values (JSONField): json field to store configurations for a site
.. no_pii:
"""
site = models.ForeignKey(Site, related_name='configuration_histories', on_delete=models.CASCADE)
enabled = models.BooleanField(default=False, verbose_name=u"Enabled")
site_values = JSONField(
null=False,
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,
......@@ -185,6 +203,7 @@ def update_site_configuration_history(sender, instance, **kwargs): # pylint: di
"""
SiteConfigurationHistory.objects.create(
site=instance.site,
site_values=instance.values,
values=instance.values,
enabled=instance.enabled,
)
......@@ -14,33 +14,39 @@ class SiteMixin(object):
super(SiteMixin, self).setUp()
self.site = SiteFactory.create()
site_config = {
"SITE_NAME": self.site.domain,
"course_email_from_addr": "fake@example.com",
"course_email_template_name": "fake_email_template",
"course_org_filter": "fakeX"
}
self.site_configuration = SiteConfigurationFactory.create(
site=self.site,
values={
"SITE_NAME": self.site.domain,
"course_email_from_addr": "fake@example.com",
"course_email_template_name": "fake_email_template",
"course_org_filter": "fakeX"
}
site_values=site_config,
# TODO: Remove this deprecated value eventually.
values=site_config
)
self.site_other = SiteFactory.create(
domain='testserver.fakeother',
name='testserver.fakeother'
)
site_config_other = {
"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"
}
}
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"
}
}
site_values=site_config_other,
# TODO: Remove this deprecated value eventually.
values=site_config_other
)
# Initialize client with default site domain
......@@ -56,6 +62,8 @@ class SiteMixin(object):
)
__ = SiteConfigurationFactory.create(
site=site,
site_values=site_configuration_values,
# TODO: Remove this deprecated value eventually.
values=site_configuration_values
)
self.use_site(site)
......
......@@ -38,6 +38,9 @@ class SessionCookieDomainTests(TestCase):
)
self.site_configuration = SiteConfigurationFactory.create(
site=self.site,
site_values={
"SESSION_COOKIE_DOMAIN": self.site.domain,
},
values={
"SESSION_COOKIE_DOMAIN": self.site.domain,
}
......@@ -73,6 +76,9 @@ class SessionCookieDomainSiteConfigurationOverrideTests(TestCase):
)
self.site_configuration = SiteConfigurationFactory.create(
site=self.site,
site_values={
"SESSION_COOKIE_DOMAIN": self.site.domain,
},
values={
"SESSION_COOKIE_DOMAIN": self.site.domain,
}
......
......@@ -82,6 +82,8 @@ class SiteConfigurationTests(TestCase):
site=self.site,
)
site_configuration.site_values = {'test': 'test'}
# TODO: Remove this deprecated value eventually.
site_configuration.values = {'test': 'test'}
site_configuration.save()
......@@ -131,6 +133,8 @@ class SiteConfigurationTests(TestCase):
# add SiteConfiguration to database
site_configuration = SiteConfigurationFactory.create(
site=self.site,
site_values=self.test_config1,
# TODO: Remove this deprecated value eventually.
values=self.test_config1,
)
......@@ -179,6 +183,8 @@ class SiteConfigurationTests(TestCase):
# add SiteConfiguration to database
site_configuration = SiteConfigurationFactory.create(
site=self.site,
site_values=invalid_data,
# TODO: Remove this deprecated value eventually.
values=invalid_data,
)
......@@ -200,10 +206,14 @@ class SiteConfigurationTests(TestCase):
# add SiteConfiguration to database
SiteConfigurationFactory.create(
site=self.site,
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,
# TODO: Remove this deprecated value eventually.
values=self.test_config2,
)
......@@ -285,10 +295,14 @@ class SiteConfigurationTests(TestCase):
# add SiteConfiguration to database
config1 = SiteConfigurationFactory.create(
site=self.site,
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,
# TODO: Remove this deprecated value eventually.
values=self.test_config2,
)
......@@ -314,10 +328,14 @@ class SiteConfigurationTests(TestCase):
# add SiteConfiguration to database
SiteConfigurationFactory.create(
site=self.site,
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,
# TODO: Remove this deprecated value eventually.
values=self.test_config2,
)
......@@ -332,11 +350,15 @@ class SiteConfigurationTests(TestCase):
# add SiteConfiguration to database
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,
# TODO: Remove this deprecated value eventually.
values=self.test_config2,
)
......
......@@ -29,9 +29,10 @@ 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, "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()
......@@ -56,9 +57,10 @@ 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, "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()
......
......@@ -109,7 +109,12 @@ class Command(BaseCommand):
SiteTheme.objects.create(site=site, theme_dir_name=theme_dir_name)
LOG.info(u"Creating '{site_name}' SiteConfiguration".format(site_name=site_domain))
SiteConfiguration.objects.create(site=site, values=site_configuration, enabled=True)
SiteConfiguration.objects.create(
site=site,
site_values=site_configuration,
values=site_configuration,
enabled=True
)
else:
LOG.info(u"'{site_domain}' site already exists".format(site_domain=site_domain))
......
......@@ -31,6 +31,7 @@ class TestHubspotSyncCommand(TestCase):
super(TestHubspotSyncCommand, cls).setUpClass()
cls.site_config = SiteConfigurationFactory()
cls.hubspot_site_config = SiteConfigurationFactory.create(
site_values={'HUBSPOT_API_KEY': 'test_key'},
values={'HUBSPOT_API_KEY': 'test_key'},
)
cls.users = []
......
......@@ -131,8 +131,14 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
# 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})
non_test_site_cfg_enabled = SiteConfigurationFactory.create(
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},
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)
......@@ -143,7 +149,10 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
# Set up test objects
test_course = CourseOverviewFactory.create(org='test-org')
test_site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': test_course.org})
test_site_cfg = SiteConfigurationFactory.create(
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))
ContentTypeGatingConfig.objects.create(course=test_course, enabled=course_setting, enabled_as_of=datetime(2018, 1, 1))
......@@ -166,7 +175,10 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
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(values={'course_org_filter': []})
test_site_cfg = SiteConfigurationFactory.create(
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):
......@@ -279,7 +291,10 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
def test_caching_org(self):
course = CourseOverviewFactory.create(org='test-org')
site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': course.org})
site_cfg = SiteConfigurationFactory.create(
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()
......@@ -324,7 +339,10 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
def test_caching_course(self):
course = CourseOverviewFactory.create(org='test-org')
site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': course.org})
site_cfg = SiteConfigurationFactory.create(
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()
......
......@@ -142,9 +142,11 @@ 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},
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},
values={'course_org_filter': non_test_course_disabled.org}
)
......@@ -157,7 +159,10 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase):
# Set up test objects
test_course = CourseOverviewFactory.create(org='test-org')
test_site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': test_course.org})
test_site_cfg = SiteConfigurationFactory.create(
site_values={'course_org_filter': test_course.org},
values={'course_org_filter': test_course.org}
)
if reverse_order:
CourseDurationLimitConfig.objects.create(site=test_site_cfg.site, enabled=site_setting)
......@@ -185,7 +190,10 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase):
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': []})
test_site_cfg = SiteConfigurationFactory.create(
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)
)
......@@ -301,7 +309,10 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase):
def test_caching_org(self):
course = CourseOverviewFactory.create(org='test-org')
site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': course.org})
site_cfg = SiteConfigurationFactory.create(
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()
......@@ -346,7 +357,10 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase):
def test_caching_course(self):
course = CourseOverviewFactory.create(org='test-org')
site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': course.org})
site_cfg = SiteConfigurationFactory.create(
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()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment