Merge pull request #4771 from edx/cdodge/ecommerce-invoicing

Cdodge/ecommerce invoicing
This commit is contained in:
chrisndodge
2014-09-02 15:32:41 -04:00
30 changed files with 3021 additions and 304 deletions

View File

@@ -15,6 +15,8 @@ from xmodule.error_module import ErrorDescriptor
from django.test.client import Client
from student.models import CourseEnrollment
from student.views import get_course_enrollment_pairs
import unittest
from django.conf import settings
class TestCourseListing(ModuleStoreTestCase):
@@ -54,6 +56,7 @@ class TestCourseListing(ModuleStoreTestCase):
self.client.logout()
super(TestCourseListing, self).tearDown()
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_get_course_list(self):
"""
Test getting courses

View File

@@ -32,6 +32,7 @@ from student.tests.factories import UserFactory, CourseModeFactory
from certificates.models import CertificateStatuses
from certificates.tests.factories import GeneratedCertificateFactory
import shoppingcart
from bulk_email.models import Optout
log = logging.getLogger(__name__)
@@ -265,6 +266,50 @@ class DashboardTest(TestCase):
verified_mode.save()
self.assertFalse(enrollment.refundable())
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@patch('courseware.views.log.warning')
def test_blocked_course_scenario(self, log_warning):
self.client.login(username="jack", password="test")
#create testing invoice 1
sale_invoice_1 = shoppingcart.models.Invoice.objects.create(
total_amount=1234.32, company_name='Test1', company_contact_name='Testw',
company_contact_email='test1@test.com', customer_reference_number='2Fwe23S',
recipient_name='Testw_1', recipient_email='test2@test.com', internal_reference="A",
course_id=self.course.id, is_valid=False
)
course_reg_code = shoppingcart.models.CourseRegistrationCode(code="abcde", course_id=self.course.id,
created_by=self.user, invoice=sale_invoice_1)
course_reg_code.save()
cart = shoppingcart.models.Order.get_cart_for_user(self.user)
shoppingcart.models.PaidCourseRegistration.add_to_order(cart, self.course.id)
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': course_reg_code.code})
self.assertEqual(resp.status_code, 200)
# freely enroll the user into course
resp = self.client.get(reverse('shoppingcart.views.register_courses'))
self.assertIn('success', resp.content)
response = self.client.get(reverse('dashboard'))
self.assertIn('You can no longer access this course because payment has not yet been received', response.content)
optout_object = Optout.objects.filter(user=self.user, course_id=self.course.id)
self.assertEqual(len(optout_object), 1)
# Direct link to course redirect to user dashboard
self.client.get(reverse('courseware', kwargs={"course_id": self.course.id.to_deprecated_string()}))
log_warning.assert_called_with(
u'User %s cannot access the course %s because payment has not yet been received', self.user, self.course.id.to_deprecated_string())
# Now re-validating the invoice
invoice = shoppingcart.models.Invoice.objects.get(id=sale_invoice_1.id)
invoice.is_valid = True
invoice.save()
response = self.client.get(reverse('dashboard'))
self.assertNotIn('You can no longer access this course because payment has not yet been received', response.content)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_refundable_of_purchased_course(self):
@@ -315,6 +360,7 @@ class EnrollInCourseTest(TestCase):
self.mock_tracker = patcher.start()
self.addCleanup(patcher.stop)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_enrollment(self):
user = User.objects.create_user("joe", "joe@joe.com", "password")
course_id = SlashSeparatedCourseKey("edX", "Test101", "2013")
@@ -419,6 +465,7 @@ class EnrollInCourseTest(TestCase):
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id))
self.assert_enrollment_event_was_emitted(user, course_id)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_enrollment_by_email(self):
user = User.objects.create(username="jack", email="jack@fake.edx.org")
course_id = SlashSeparatedCourseKey("edX", "Test101", "2013")
@@ -456,6 +503,7 @@ class EnrollInCourseTest(TestCase):
CourseEnrollment.unenroll_by_email("not_jack@fake.edx.org", course_id)
self.assert_no_events_were_emitted()
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_enrollment_multiple_classes(self):
user = User(username="rusty", email="rusty@fake.edx.org")
course_id1 = SlashSeparatedCourseKey("edX", "Test101", "2013")
@@ -478,6 +526,7 @@ class EnrollInCourseTest(TestCase):
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id1))
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id2))
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_activation(self):
user = User.objects.create(username="jack", email="jack@fake.edx.org")
course_id = SlashSeparatedCourseKey("edX", "Test101", "2013")

View File

@@ -92,6 +92,7 @@ from util.password_policy_validators import (
from third_party_auth import pipeline, provider
from xmodule.error_module import ErrorDescriptor
from shoppingcart.models import CourseRegistrationCode
import analytics
from eventtracking import tracker
@@ -431,6 +432,20 @@ def complete_course_mode_info(course_id, enrollment):
return mode_info
def is_course_blocked(request, redeemed_registration_codes, course_key):
"""Checking either registration is blocked or not ."""
blocked = False
for redeemed_registration in redeemed_registration_codes:
if not getattr(redeemed_registration.invoice, 'is_valid'):
blocked = True
# disabling email notifications for unpaid registration courses
Optout.objects.get_or_create(user=request.user, course_id=course_key)
log.info(u"User {0} ({1}) opted out of receiving emails from course {2}".format(request.user.username, request.user.email, course_key))
track.views.server_track(request, "change-email1-settings", {"receive_emails": "no", "course": course_key.to_deprecated_string()}, page='dashboard')
break
return blocked
@login_required
@ensure_csrf_cookie
def dashboard(request):
@@ -493,6 +508,10 @@ def dashboard(request):
show_refund_option_for = frozenset(course.id for course, _enrollment in course_enrollment_pairs
if _enrollment.refundable())
block_courses = frozenset(course.id for course, enrollment in course_enrollment_pairs
if is_course_blocked(request, CourseRegistrationCode.objects.filter(course_id=course.id, registrationcoderedemption__redeemed_by=request.user), course.id))
enrolled_courses_either_paid = frozenset(course.id for course, _enrollment in course_enrollment_pairs
if _enrollment.is_paid_course())
# get info w.r.t ExternalAuthMap
@@ -544,6 +563,7 @@ def dashboard(request):
'verification_status': verification_status,
'verification_msg': verification_msg,
'show_refund_option_for': show_refund_option_for,
'block_courses': block_courses,
'denied_banner': denied_banner,
'billing_email': settings.PAYMENT_SUPPORT_EMAIL,
'language_options': language_options,