From 191a353078aab60dfe06a211d5d87e391ac7b690 Mon Sep 17 00:00:00 2001 From: Renzo Lucioni Date: Fri, 8 Jul 2016 16:06:45 -0400 Subject: [PATCH] Add ConfigurationModel governing integration with the catalog service. This is the first in a series of commits that will retrieve and use data from the catalog API. Part of ECOM-4566. --- cms/envs/common.py | 3 ++ lms/envs/common.py | 3 ++ openedx/core/djangoapps/catalog/__init__.py | 0 .../catalog/migrations/0001_initial.py | 31 +++++++++++++++++ .../djangoapps/catalog/migrations/__init__.py | 0 openedx/core/djangoapps/catalog/models.py | 34 +++++++++++++++++++ .../core/djangoapps/catalog/tests/__init__.py | 0 .../core/djangoapps/catalog/tests/mixins.py | 19 +++++++++++ .../djangoapps/catalog/tests/test_models.py | 23 +++++++++++++ 9 files changed, 113 insertions(+) create mode 100644 openedx/core/djangoapps/catalog/__init__.py create mode 100644 openedx/core/djangoapps/catalog/migrations/0001_initial.py create mode 100644 openedx/core/djangoapps/catalog/migrations/__init__.py create mode 100644 openedx/core/djangoapps/catalog/models.py create mode 100644 openedx/core/djangoapps/catalog/tests/__init__.py create mode 100644 openedx/core/djangoapps/catalog/tests/mixins.py create mode 100644 openedx/core/djangoapps/catalog/tests/test_models.py diff --git a/cms/envs/common.py b/cms/envs/common.py index dc5ee57fcb..d05ada40dc 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -898,6 +898,9 @@ INSTALLED_APPS = ( # programs support 'openedx.core.djangoapps.programs', + # Catalog integration + 'openedx.core.djangoapps.catalog', + # Self-paced course configuration 'openedx.core.djangoapps.self_paced', diff --git a/lms/envs/common.py b/lms/envs/common.py index acefa2c36e..378c43a7a9 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -2039,6 +2039,9 @@ INSTALLED_APPS = ( # programs support 'openedx.core.djangoapps.programs', + # Catalog integration + 'openedx.core.djangoapps.catalog', + # Self-paced course configuration 'openedx.core.djangoapps.self_paced', diff --git a/openedx/core/djangoapps/catalog/__init__.py b/openedx/core/djangoapps/catalog/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/openedx/core/djangoapps/catalog/migrations/0001_initial.py b/openedx/core/djangoapps/catalog/migrations/0001_initial.py new file mode 100644 index 0000000000..4c934f57ac --- /dev/null +++ b/openedx/core/djangoapps/catalog/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='CatalogIntegration', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('change_date', models.DateTimeField(auto_now_add=True, verbose_name='Change date')), + ('enabled', models.BooleanField(default=False, verbose_name='Enabled')), + ('internal_api_url', models.URLField(help_text='API root to be used for server-to-server requests (e.g., https://catalog-internal.example.com/api/v1/).', verbose_name='Internal API URL')), + ('cache_ttl', models.PositiveIntegerField(default=0, help_text='Specified in seconds. Enable caching of API responses by setting this to a value greater than 0.', verbose_name='Cache Time To Live')), + ('changed_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Changed by')), + ], + options={ + 'ordering': ('-change_date',), + 'abstract': False, + }, + ), + ] diff --git a/openedx/core/djangoapps/catalog/migrations/__init__.py b/openedx/core/djangoapps/catalog/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/openedx/core/djangoapps/catalog/models.py b/openedx/core/djangoapps/catalog/models.py new file mode 100644 index 0000000000..1d01d90b71 --- /dev/null +++ b/openedx/core/djangoapps/catalog/models.py @@ -0,0 +1,34 @@ +"""Models governing integration with the catalog service.""" +from django.utils.translation import ugettext_lazy as _ +from django.db import models + +from config_models.models import ConfigurationModel + + +class CatalogIntegration(ConfigurationModel): + """Manages configuration for connecting to the catalog service and using its API.""" + API_NAME = 'catalog' + CACHE_KEY = 'catalog.api.data' + + internal_api_url = models.URLField( + verbose_name=_('Internal API URL'), + help_text=_( + 'API root to be used for server-to-server requests (e.g., https://catalog-internal.example.com/api/v1/).' + ) + ) + + cache_ttl = models.PositiveIntegerField( + verbose_name=_('Cache Time To Live'), + default=0, + help_text=_( + 'Specified in seconds. Enable caching of API responses by setting this to a value greater than 0.' + ) + ) + + @property + def is_cache_enabled(self): + """Whether responses from the catalog API will be cached.""" + return self.cache_ttl > 0 + + def __unicode__(self): + return self.internal_api_url diff --git a/openedx/core/djangoapps/catalog/tests/__init__.py b/openedx/core/djangoapps/catalog/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/openedx/core/djangoapps/catalog/tests/mixins.py b/openedx/core/djangoapps/catalog/tests/mixins.py new file mode 100644 index 0000000000..2372a0b33f --- /dev/null +++ b/openedx/core/djangoapps/catalog/tests/mixins.py @@ -0,0 +1,19 @@ +"""Mixins to help test catalog integration.""" +from openedx.core.djangoapps.catalog.models import CatalogIntegration + + +class CatalogIntegrationMixin(object): + """Utility for working with the catalog service during testing.""" + + DEFAULTS = { + 'enabled': True, + 'internal_api_url': 'https://catalog-internal.example.com/api/v1/', + 'cache_ttl': 0, + } + + def create_catalog_integration(self, **kwargs): + """Creates a new CatalogIntegration with DEFAULTS, updated with any provided overrides.""" + fields = dict(self.DEFAULTS, **kwargs) + CatalogIntegration(**fields).save() + + return CatalogIntegration.current() diff --git a/openedx/core/djangoapps/catalog/tests/test_models.py b/openedx/core/djangoapps/catalog/tests/test_models.py new file mode 100644 index 0000000000..1854e1d5f8 --- /dev/null +++ b/openedx/core/djangoapps/catalog/tests/test_models.py @@ -0,0 +1,23 @@ +"""Catalog model tests.""" +import ddt +from django.test import TestCase +import mock + +from openedx.core.djangoapps.catalog.tests import mixins + + +@ddt.ddt +# ConfigurationModels use the cache. Make every cache get a miss. +@mock.patch('config_models.models.cache.get', return_value=None) +class TestCatalogIntegration(mixins.CatalogIntegrationMixin, TestCase): + """Tests covering the CatalogIntegration model.""" + + @ddt.data( + (0, False), + (1, True), + ) + @ddt.unpack + def test_cache_control(self, cache_ttl, is_cache_enabled, _mock_cache): + """Test the behavior of the property controlling whether API responses are cached.""" + catalog_integration = self.create_catalog_integration(cache_ttl=cache_ttl) + self.assertEqual(catalog_integration.is_cache_enabled, is_cache_enabled)