diff --git a/lms/djangoapps/commerce/management/__init__.py b/lms/djangoapps/commerce/management/__init__.py new file mode 100644 index 0000000000..c668187b6e --- /dev/null +++ b/lms/djangoapps/commerce/management/__init__.py @@ -0,0 +1,3 @@ +""" +Management commands related to commerce configuration. +""" diff --git a/lms/djangoapps/commerce/management/commands/__init__.py b/lms/djangoapps/commerce/management/commands/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lms/djangoapps/commerce/management/commands/configure_commerce.py b/lms/djangoapps/commerce/management/commands/configure_commerce.py new file mode 100644 index 0000000000..86b9310091 --- /dev/null +++ b/lms/djangoapps/commerce/management/commands/configure_commerce.py @@ -0,0 +1,68 @@ +""" +Command for managing commerce configuration for lms. +We can use this command to enable/disable commerce configuration or disable checkout to E-Commerce service. +""" + +from __future__ import unicode_literals +import logging + +from django.core.management import BaseCommand + +from commerce.models import CommerceConfiguration + +logger = logging.getLogger(__name__) # pylint: disable=invalid-name + + +class Command(BaseCommand): + """ + Command to enable or disable commerce configuration. + + Positional Arguments: + This command does not take any positional argument. + + Optional Arguments: + disable (bool): if True then disable configuration, enable otherwise + checkout_on_ecommerce (bool): Enable E-Commerce checkout if True, disable otherwise. + """ + help = 'Enable/Disable commerce configuration, including configuration of E-Commerce checkout.' + + def add_arguments(self, parser): + parser.add_argument('--disable-checkout-on-ecommerce', + dest='checkout_on_ecommerce', + action='store_false', + default=True, + help='Do not checkout to E-Commerce even when configuration is enabled.') + parser.add_argument('--disable', + dest='disable', + action='store_true', + default=False, + help='Disable existing E-Commerce configuration.') + + def handle(self, *args, **options): + """ + Create a new commerce configuration or update an existing one according to the command line arguments. + + args: + This command does not take any positional argument. + + options: + disable (bool): if True then disable configuration, enable otherwise + checkout_on_ecommerce (bool): Enable E-Commerce checkout if True, disable otherwise. + """ + disable = options.get('disable') + checkout_on_ecommerce = options.get('checkout_on_ecommerce') + + # We are keeping id=1, because as of now, there are only one commerce configuration for the system. + CommerceConfiguration.objects.update_or_create( # pylint: disable=no-member + id=1, + defaults={ + 'enabled': not disable, + 'checkout_on_ecommerce_service': checkout_on_ecommerce, + } + ) + logger.info( + 'Commerce Configuration {configuration_status} with checkout on ecommerce {checkout_status}.'.format( + configuration_status="disabled" if disable else "enabled", + checkout_status="enabled" if checkout_on_ecommerce else "disabled", + ), + ) diff --git a/lms/djangoapps/commerce/management/commands/tests/__init__.py b/lms/djangoapps/commerce/management/commands/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lms/djangoapps/commerce/management/commands/tests/test_configure_commerce.py b/lms/djangoapps/commerce/management/commands/tests/test_configure_commerce.py new file mode 100644 index 0000000000..a3800314c4 --- /dev/null +++ b/lms/djangoapps/commerce/management/commands/tests/test_configure_commerce.py @@ -0,0 +1,58 @@ +""" +Tests for management command for enabling commerce configuration. +""" +from django.test import TestCase +from django.core.management import call_command + +from commerce.models import CommerceConfiguration + + +class TestCommerceConfigurationCommand(TestCase): + """ + Test django management command for enabling commerce configuration. + """ + def test_commerce_configuration(self): + """ + Test that commerce configuration is created properly. + """ + call_command( + "configure_commerce", + ) + + # Verify commerce configuration is enabled with appropriate values + commerce_configuration = CommerceConfiguration.current() + + self.assertTrue(commerce_configuration.enabled) + self.assertTrue(commerce_configuration.checkout_on_ecommerce_service) + self.assertEqual(commerce_configuration.single_course_checkout_page, "/basket/single-item/") + self.assertEqual(commerce_configuration.cache_ttl, 0) + + # Verify commerce configuration can be disabled from command + call_command( + "configure_commerce", + '--disable', + ) + + commerce_configuration = CommerceConfiguration.current() + self.assertFalse(commerce_configuration.enabled) + + # Verify commerce configuration can be disabled from command + call_command( + "configure_commerce", + '--disable-checkout-on-ecommerce', + ) + + commerce_configuration = CommerceConfiguration.current() + self.assertFalse(commerce_configuration.checkout_on_ecommerce_service) + + def test_site_associated_commerce_configuration(self): + """ + This test is added here to fail when site_id field is added. + + This is done to make sure that this command gets updated once site_id field is added to + CommerceConfiguration model. + """ + self.assertFalse( + hasattr(CommerceConfiguration, "site"), + "Update configure_commerce command to account for site specific configurations.", + )