Commit 6672f641 by John Eskew

Add commerce AppConfig and use to register signals. Move imports.

Add explicit 'lms.djangoapps' prefix to all commerce imports, as another
commerce Django app exists at openedx.core.djangoapps.commerce
parent ac3642ad
......@@ -203,7 +203,7 @@ class RefundableTest(SharedModuleStoreTestCase):
raised while getting order detail for ecommerce.
"""
# importing this after overriding value of ECOMMERCE_API_URL
from commerce.tests.mocks import mock_order_endpoint
from lms.djangoapps.commerce.tests.mocks import mock_order_endpoint
self.client.login(username=self.user.username, password=self.USER_PASSWORD)
with mock_order_endpoint(order_number=self.ORDER_NUMBER, exception=exception, reset_on_exit=False):
......
......@@ -95,7 +95,7 @@ class TestStudentDashboardUnenrollments(SharedModuleStoreTestCase):
self.cert_status = cert_status
with patch('student.views.cert_info', side_effect=self.mock_cert):
with patch('commerce.signals.handle_refund_order') as mock_refund_handler:
with patch('lms.djangoapps.commerce.signals.handle_refund_order') as mock_refund_handler:
REFUND_ORDER.connect(mock_refund_handler)
response = self.client.post(
reverse('change_enrollment'),
......
""" Commerce app. """
# this is here to support registering the signals in signals.py
from commerce import signals
......@@ -3,6 +3,6 @@
from config_models.admin import ConfigurationModelAdmin
from django.contrib import admin
from commerce.models import CommerceConfiguration
from .models import CommerceConfiguration
admin.site.register(CommerceConfiguration, ConfigurationModelAdmin)
......@@ -4,6 +4,6 @@ API URLs.
from django.conf.urls import include, url
urlpatterns = [
url(r'^v0/', include('commerce.api.v0.urls', namespace='v0')),
url(r'^v1/', include('commerce.api.v1.urls', namespace='v1')),
url(r'^v0/', include('lms.djangoapps.commerce.api.v0.urls', namespace='v0')),
url(r'^v1/', include('lms.djangoapps.commerce.api.v1.urls', namespace='v1')),
]
......@@ -14,12 +14,13 @@ from django.test.utils import override_settings
from edx_rest_api_client import exceptions
from nose.plugins.attrib import attr
from commerce.api.v0.views import SAILTHRU_CAMPAIGN_COOKIE
from commerce.constants import Messages
from commerce.tests.mocks import mock_basket_order
from commerce.tests.test_views import UserMixin
from course_modes.models import CourseMode
from course_modes.tests.factories import CourseModeFactory
from enrollment.api import get_enrollment
from ..views import SAILTHRU_CAMPAIGN_COOKIE
from ....constants import Messages
from ....tests.mocks import mock_basket_order
from ....tests.test_views import UserMixin
from openedx.core.djangoapps.embargo.test_utils import restrict_course
from openedx.core.lib.django_test_client_utils import get_absolute_url
from student.models import CourseEnrollment
......@@ -250,7 +251,7 @@ class BasketsViewTests(EnrollmentEventTestMixin, UserMixin, ModuleStoreTestCase)
self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course.id))
self.assertIsNotNone(get_enrollment(self.user.username, unicode(self.course.id)))
@mock.patch('commerce.api.v0.views.update_email_opt_in')
@mock.patch('lms.djangoapps.commerce.api.v0.views.update_email_opt_in')
@ddt.data(*itertools.product((False, True), (False, True), (False, True)))
@ddt.unpack
def test_marketing_email_opt_in(self, is_opt_in, has_sku, is_exception, mock_update):
......
......@@ -3,7 +3,7 @@ API v0 URLs.
"""
from django.conf.urls import include, url
from commerce.api.v0 import views
from . import views
BASKET_URLS = [
url(r'^$', views.BasketsView.as_view(), name='create'),
......
......@@ -9,12 +9,12 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.status import HTTP_406_NOT_ACCEPTABLE, HTTP_409_CONFLICT
from rest_framework.views import APIView
from commerce.constants import Messages
from commerce.http import DetailResponse
from course_modes.models import CourseMode
from courseware import courses
from enrollment.api import add_enrollment
from enrollment.views import EnrollmentCrossDomainSessionAuth
from ...constants import Messages
from ...http import DetailResponse
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client
from openedx.core.djangoapps.embargo import api as embargo_api
from openedx.core.djangoapps.user_api.preferences.api import update_email_opt_in
......
......@@ -3,7 +3,7 @@ from django.conf import settings
from django.contrib.auth.models import User
from rest_framework.permissions import BasePermission, DjangoModelPermissions
from commerce.utils import is_account_activation_requirement_disabled
from ...utils import is_account_activation_requirement_disabled
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.lib.api.permissions import ApiKeyHeaderPermission
......
......@@ -7,8 +7,8 @@ from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from rest_framework import serializers
from commerce.api.v1.models import Course
from course_modes.models import CourseMode
from .models import Course
from xmodule.modulestore.django import modulestore
......
......@@ -2,8 +2,8 @@
import ddt
from django.test import TestCase
from commerce.api.v1.models import Course
from course_modes.models import CourseMode
from ..models import Course
@ddt.ddt
......
""" Commerce API v1 serializer tests. """
from django.test import TestCase
from commerce.api.v1.serializers import serializers, validate_course_id
from ..serializers import serializers, validate_course_id
class CourseValidatorTests(TestCase):
......
......@@ -14,9 +14,9 @@ from edx_rest_api_client import exceptions
from nose.plugins.attrib import attr
from rest_framework.utils.encoders import JSONEncoder
from commerce.tests.mocks import mock_order_endpoint
from commerce.tests.test_views import UserMixin
from course_modes.models import CourseMode
from ....tests.mocks import mock_order_endpoint
from ....tests.test_views import UserMixin
from lms.djangoapps.verify_student.models import VerificationDeadline
from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
......
""" API v1 URLs. """
from django.conf import settings
from django.conf.urls import include, url
from commerce.api.v1 import views
from . import views
COURSE_URLS = [
url(r'^$', views.CourseListView.as_view(), name='list'),
......
......@@ -10,11 +10,11 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework_oauth.authentication import OAuth2Authentication
from commerce.api.v1.models import Course
from commerce.api.v1.permissions import ApiKeyOrModelPermission, IsAuthenticatedOrActivationOverridden
from commerce.api.v1.serializers import CourseSerializer
from commerce.utils import is_account_activation_requirement_disabled
from course_modes.models import CourseMode
from .models import Course
from .permissions import ApiKeyOrModelPermission, IsAuthenticatedOrActivationOverridden
from .serializers import CourseSerializer
from ...utils import is_account_activation_requirement_disabled
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client
from openedx.core.lib.api.mixins import PutAsCreateMixin
from util.json_request import JsonResponse
......
"""
Commerce Application Configuration
"""
from django.apps import AppConfig
class CommerceConfig(AppConfig):
"""
Application Configuration for Commerce.
"""
name = 'lms.djangoapps.commerce'
def ready(self):
"""
Connect handlers to signals.
"""
from . import signals # pylint: disable=unused-variable
......@@ -9,7 +9,7 @@ import logging
from django.core.management import BaseCommand
from commerce.models import CommerceConfiguration
from ...models import CommerceConfiguration
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
......
......@@ -4,7 +4,7 @@ Tests for management command for enabling commerce configuration.
from django.core.management import call_command
from django.test import TestCase
from commerce.models import CommerceConfiguration
from ....models import CommerceConfiguration
class TestCommerceConfigurationCommand(TestCase):
......
......@@ -10,9 +10,12 @@ from urlparse import urljoin
import requests
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser
from django.dispatch import receiver
from django.utils.translation import ugettext as _
from .models import CommerceConfiguration
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client, is_commerce_service_configured
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.theming import helpers as theming_helpers
from request_cache.middleware import RequestCache
......@@ -28,10 +31,6 @@ def handle_refund_order(sender, course_enrollment=None, **kwargs):
Signal receiver for unenrollments, used to automatically initiate refunds
when applicable.
"""
# Import is placed here to avoid model import at project startup.
from django.contrib.auth.models import AnonymousUser
from openedx.core.djangoapps.commerce.utils import is_commerce_service_configured
if not is_commerce_service_configured():
return
......@@ -84,10 +83,6 @@ def refund_seat(course_enrollment):
exceptions.SlumberBaseException: for any unhandled HTTP error during communication with the E-Commerce Service.
exceptions.Timeout: if the attempt to reach the commerce service timed out.
"""
# Import is placed here to avoid model import at project startup.
from commerce.models import CommerceConfiguration
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client
User = get_user_model() # pylint:disable=invalid-name
course_key_str = unicode(course_enrollment.course_id)
enrollee = course_enrollment.user
......
......@@ -4,7 +4,7 @@ import json
import httpretty
from django.conf import settings
from commerce.tests import factories
from . import factories
# pylint: disable=invalid-name
......
......@@ -18,11 +18,15 @@ from django.test.utils import override_settings
from opaque_keys.edx.keys import CourseKey
from requests import Timeout
from commerce.models import CommerceConfiguration
from commerce.signals import create_zendesk_ticket, generate_refund_notification_body, send_refund_notification
from commerce.tests import JSON
from commerce.tests.mocks import mock_create_refund, mock_process_refund
from course_modes.models import CourseMode
from ..models import CommerceConfiguration
from ..signals import (
create_zendesk_ticket,
generate_refund_notification_body,
send_refund_notification
)
from . import JSON
from .mocks import mock_create_refund, mock_process_refund
from student.signals import REFUND_ORDER
from student.tests.factories import CourseEnrollmentFactory, UserFactory
......@@ -76,11 +80,11 @@ class TestRefundSignal(TestCase):
Ensure that the receiver quietly bypasses attempts to initiate
refunds when there is no external service configured.
"""
with mock.patch('commerce.signals.refund_seat') as mock_refund_seat:
with mock.patch('lms.djangoapps.commerce.signals.refund_seat') as mock_refund_seat:
self.send_signal()
self.assertFalse(mock_refund_seat.called)
@mock.patch('commerce.signals.refund_seat')
@mock.patch('lms.djangoapps.commerce.signals.refund_seat')
def test_receiver(self, mock_refund_seat):
"""
Ensure that the REFUND_ORDER signal triggers correct calls to
......@@ -100,8 +104,8 @@ class TestRefundSignal(TestCase):
self.send_signal()
self.assertFalse(mock_refund_seat.called)
@mock.patch('commerce.signals.refund_seat')
@mock.patch('commerce.signals.get_request_user', return_value=None)
@mock.patch('lms.djangoapps.commerce.signals.refund_seat')
@mock.patch('lms.djangoapps.commerce.signals.get_request_user', return_value=None)
def test_requester(self, mock_get_request_user, mock_refund_seat):
"""
Ensure the right requester is specified when initiating refunds.
......@@ -131,7 +135,7 @@ class TestRefundSignal(TestCase):
self.send_signal()
self.assertFalse(mock_refund_seat.called)
@mock.patch('commerce.signals.log.exception')
@mock.patch('lms.djangoapps.commerce.signals.log.exception')
def test_error_logging(self, mock_log_exception):
"""
Ensure that unexpected Exceptions are logged as errors (but do not
......@@ -141,7 +145,7 @@ class TestRefundSignal(TestCase):
self.send_signal()
self.assertTrue(mock_log_exception.called)
@mock.patch('commerce.signals.send_refund_notification')
@mock.patch('lms.djangoapps.commerce.signals.send_refund_notification')
def test_notification_when_approval_fails(self, mock_send_notification):
"""
Ensure the notification function is triggered when refunds are initiated, and cannot be automatically approved.
......@@ -156,7 +160,7 @@ class TestRefundSignal(TestCase):
self.assertTrue(mock_send_notification.called)
mock_send_notification.assert_called_with(self.course_enrollment, [failed_refund_id])
@mock.patch('commerce.signals.send_refund_notification')
@mock.patch('lms.djangoapps.commerce.signals.send_refund_notification')
def test_notification_if_automatic_approval_disabled(self, mock_send_notification):
"""
Ensure the notification is always sent if the automatic approval functionality is disabled.
......@@ -170,7 +174,7 @@ class TestRefundSignal(TestCase):
self.assertTrue(mock_send_notification.called)
mock_send_notification.assert_called_with(self.course_enrollment, [refund_id])
@mock.patch('commerce.signals.send_refund_notification')
@mock.patch('lms.djangoapps.commerce.signals.send_refund_notification')
def test_no_notification_after_approval(self, mock_send_notification):
"""
Ensure the notification function is triggered when refunds are initiated, and cannot be automatically approved.
......@@ -185,7 +189,7 @@ class TestRefundSignal(TestCase):
last_request = httpretty.last_request()
self.assertDictEqual(json.loads(last_request.body), {'action': 'approve_payment_only'})
@mock.patch('commerce.signals.send_refund_notification')
@mock.patch('lms.djangoapps.commerce.signals.send_refund_notification')
def test_notification_no_refund(self, mock_send_notification):
"""
Ensure the notification function is NOT triggered when no refunds are
......@@ -195,7 +199,7 @@ class TestRefundSignal(TestCase):
self.send_signal()
self.assertFalse(mock_send_notification.called)
@mock.patch('commerce.signals.send_refund_notification')
@mock.patch('lms.djangoapps.commerce.signals.send_refund_notification')
@ddt.data(
CourseMode.HONOR,
CourseMode.PROFESSIONAL,
......@@ -216,8 +220,8 @@ class TestRefundSignal(TestCase):
self.send_signal()
self.assertFalse(mock_send_notification.called)
@mock.patch('commerce.signals.send_refund_notification', side_effect=Exception("Splat!"))
@mock.patch('commerce.signals.log.warning')
@mock.patch('lms.djangoapps.commerce.signals.send_refund_notification', side_effect=Exception("Splat!"))
@mock.patch('lms.djangoapps.commerce.signals.log.warning')
def test_notification_error(self, mock_log_warning, mock_send_notification):
"""
Ensure an error occuring during notification does not break program
......
......@@ -9,8 +9,8 @@ from django.test.utils import override_settings
from mock import patch
from waffle.testutils import override_switch
from commerce.models import CommerceConfiguration
from commerce.utils import EcommerceService
from ..models import CommerceConfiguration
from ..utils import EcommerceService
from openedx.core.lib.log_utils import audit_log
from student.tests.factories import UserFactory
......
......@@ -109,7 +109,7 @@ class ReceiptViewTests(UserMixin, ModuleStoreTestCase):
self.assertRegexpMatches(response.content, expected_pattern)
@ddt.data(True, False)
@mock.patch('commerce.views.is_user_payment_error')
@mock.patch('lms.djangoapps.commerce.views.is_user_payment_error')
def test_cybersource_message(self, is_user_message_expected, mock_is_user_payment_error):
"""
Ensure that the page displays the right message for the reason_code (it
......
......@@ -3,7 +3,7 @@ Defines the URL routes for this app.
"""
from django.conf.urls import url
from commerce import views
from . import views
urlpatterns = [
url(r'^checkout/cancel/$', views.checkout_cancel, name='checkout_cancel'),
......
......@@ -7,7 +7,7 @@ from django.conf import settings
from django.core.urlresolvers import reverse
from student.models import CourseEnrollment
from commerce.models import CommerceConfiguration
from .models import CommerceConfiguration
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
......
......@@ -10,9 +10,9 @@ from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from opaque_keys.edx.locator import CourseLocator
from commerce.models import CommerceConfiguration
from course_modes.models import CourseMode
from edxmako.shortcuts import render_to_response
from .models import CommerceConfiguration
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.theming.helpers import is_request_in_themed_site
......
......@@ -12,7 +12,7 @@ from mock import patch
from nose.plugins.attrib import attr
from pytz import utc
from commerce.models import CommerceConfiguration
from lms.djangoapps.commerce.models import CommerceConfiguration
from course_modes.models import CourseMode
from course_modes.tests.factories import CourseModeFactory
from courseware.courses import get_course_date_blocks
......
......@@ -35,7 +35,7 @@ from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory
from certificates import api as certs_api
from certificates.models import CertificateGenerationConfiguration, CertificateStatuses
from certificates.tests.factories import CertificateInvalidationFactory, GeneratedCertificateFactory
from commerce.models import CommerceConfiguration
from lms.djangoapps.commerce.models import CommerceConfiguration
from course_modes.models import CourseMode
from course_modes.tests.factories import CourseModeFactory
from courseware.access_utils import check_course_open_for_learner
......
......@@ -12,7 +12,7 @@ import shoppingcart
import survey.views
from certificates import api as certs_api
from certificates.models import CertificateStatuses
from commerce.utils import EcommerceService
from lms.djangoapps.commerce.utils import EcommerceService
from course_modes.models import (CourseMode, get_course_prices)
from courseware.access import has_access, has_ccx_coach_role
from courseware.access_utils import check_course_open_for_learner
......
......@@ -10,7 +10,7 @@ from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey, UsageKey
import lms.djangoapps.instructor.enrollment as enrollment
from commerce.signals import create_zendesk_ticket
from lms.djangoapps.commerce.signals import create_zendesk_ticket
from courseware.models import StudentModule
from lms.djangoapps.instructor.views.tools import get_student_from_identifier
from student import auth
......
......@@ -5,7 +5,7 @@ from django.http import Http404
from django.views.decorators.http import require_GET
from edxmako.shortcuts import render_to_response
from commerce.utils import EcommerceService
from lms.djangoapps.commerce.utils import EcommerceService
from lms.djangoapps.learner_dashboard.programs import ProgramsFragmentView
from lms.djangoapps.learner_dashboard.utils import FAKE_COURSE_KEY, strip_course_id
......
......@@ -27,9 +27,9 @@ from provider.oauth2.models import AccessToken as dop_access_token
from provider.oauth2.models import RefreshToken as dop_refresh_token
from testfixtures import LogCapture
from commerce.models import CommerceConfiguration
from commerce.tests import factories
from commerce.tests.mocks import mock_get_orders
from lms.djangoapps.commerce.models import CommerceConfiguration
from lms.djangoapps.commerce.tests import factories
from lms.djangoapps.commerce.tests.mocks import mock_get_orders
from course_modes.models import CourseMode
from http.cookies import SimpleCookie
from openedx.core.djangoapps.oauth_dispatch.tests import factories as dot_factories
......
......@@ -18,7 +18,7 @@ from django.views.decorators.http import require_http_methods
from django_countries import countries
import third_party_auth
from commerce.models import CommerceConfiguration
from lms.djangoapps.commerce.models import CommerceConfiguration
from edxmako.shortcuts import render_to_response
from lms.djangoapps.commerce.utils import EcommerceService
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client
......
......@@ -28,14 +28,14 @@ from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locator import CourseLocator
from waffle.testutils import override_switch
from commerce.models import CommerceConfiguration
from commerce.tests import TEST_API_URL, TEST_PAYMENT_DATA, TEST_PUBLIC_URL_ROOT
from lms.djangoapps.commerce.models import CommerceConfiguration
from lms.djangoapps.commerce.tests import TEST_API_URL, TEST_PAYMENT_DATA, TEST_PUBLIC_URL_ROOT
from common.test.utils import XssTestMixin
from course_modes.models import CourseMode
from course_modes.tests.factories import CourseModeFactory
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification, VerificationDeadline
from lms.djangoapps.verify_student.views import PayAndVerifyView, checkout_with_ecommerce_service, render_to_response
from commerce.utils import EcommerceService
from lms.djangoapps.commerce.utils import EcommerceService
from openedx.core.djangoapps.embargo.test_utils import restrict_course
from openedx.core.djangoapps.theming.tests.test_util import with_comprehensive_theme
from openedx.core.djangoapps.user_api.accounts.api import get_account_settings
......
......@@ -30,7 +30,7 @@ from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from pytz import UTC
from commerce.utils import EcommerceService, is_account_activation_requirement_disabled
from lms.djangoapps.commerce.utils import EcommerceService, is_account_activation_requirement_disabled
from course_modes.models import CourseMode
from edxmako.shortcuts import render_to_response, render_to_string
from eventtracking import tracker
......
......@@ -2243,7 +2243,7 @@ INSTALLED_APPS = [
'corsheaders',
'openedx.core.djangoapps.cors_csrf',
'commerce',
'lms.djangoapps.commerce.apps.CommerceConfig',
# Credit courses
'openedx.core.djangoapps.credit.apps.CreditConfig',
......
......@@ -847,7 +847,7 @@ if configuration_helpers.get_value('ENABLE_BULK_ENROLLMENT_VIEW', settings.FEATU
# Shopping cart
urlpatterns += [
url(r'^shoppingcart/', include('shoppingcart.urls')),
url(r'^commerce/', include('commerce.urls', namespace='commerce')),
url(r'^commerce/', include('lms.djangoapps.commerce.urls', namespace='commerce')),
]
# Course goals
......
......@@ -10,7 +10,7 @@ from freezegun import freeze_time
from mock import Mock, patch
import pytz
from commerce.models import CommerceConfiguration
from lms.djangoapps.commerce.models import CommerceConfiguration
from course_modes.models import CourseMode
from course_modes.tests.factories import CourseModeFactory
from courseware.models import DynamicUpgradeDeadlineConfiguration
......
......@@ -14,8 +14,8 @@ from pytz import UTC
from waffle.models import Flag
from waffle.testutils import override_flag
from commerce.models import CommerceConfiguration
from commerce.utils import EcommerceService
from lms.djangoapps.commerce.models import CommerceConfiguration
from lms.djangoapps.commerce.utils import EcommerceService
from lms.djangoapps.course_goals.api import add_course_goal, remove_course_goal
from course_modes.models import CourseMode
from courseware.tests.factories import StaffFactory
......
......@@ -4,7 +4,7 @@ Tests for course verification sock
import ddt
from commerce.models import CommerceConfiguration
from lms.djangoapps.commerce.models import CommerceConfiguration
from course_modes.models import CourseMode
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
from openedx.features.course_experience import DISPLAY_COURSE_SOCK_FLAG
......
......@@ -9,7 +9,7 @@ from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_control
from django.views.decorators.csrf import ensure_csrf_cookie
from commerce.utils import EcommerceService
from lms.djangoapps.commerce.utils import EcommerceService
from course_modes.models import get_cosmetic_verified_display_price
from courseware.access import has_access
from courseware.courses import (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment