Remove more references to fix tests.
This commit is contained in:
@@ -160,8 +160,6 @@ EXECUTIVE_SUMMARY_DATA = (
|
||||
INSTRUCTOR_GET_ENDPOINTS = set([
|
||||
'get_anon_ids',
|
||||
'get_issued_certificates',
|
||||
'get_sale_order_records',
|
||||
'get_sale_records',
|
||||
])
|
||||
INSTRUCTOR_POST_ENDPOINTS = set([
|
||||
'add_users_to_cohorts',
|
||||
@@ -178,12 +176,10 @@ INSTRUCTOR_POST_ENDPOINTS = set([
|
||||
'get_student_progress_url',
|
||||
'get_students_features',
|
||||
'get_students_who_may_enroll',
|
||||
'get_user_invoice_preference',
|
||||
'list_background_email_tasks',
|
||||
'list_course_role_members',
|
||||
'list_email_content',
|
||||
'list_entrance_exam_instructor_tasks',
|
||||
'list_financial_report_downloads',
|
||||
'list_forum_members',
|
||||
'list_instructor_tasks',
|
||||
'list_report_downloads',
|
||||
@@ -195,11 +191,9 @@ INSTRUCTOR_POST_ENDPOINTS = set([
|
||||
'reset_due_date',
|
||||
'reset_student_attempts',
|
||||
'reset_student_attempts_for_entrance_exam',
|
||||
'sale_validation',
|
||||
'show_student_extensions',
|
||||
'show_unit_extensions',
|
||||
'send_email',
|
||||
'spent_registration_codes',
|
||||
'students_update_enrollment',
|
||||
'update_forum_role_membership',
|
||||
'override_problem_score',
|
||||
@@ -448,7 +442,6 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
|
||||
('list_instructor_tasks', {}),
|
||||
('list_background_email_tasks', {}),
|
||||
('list_report_downloads', {}),
|
||||
('list_financial_report_downloads', {}),
|
||||
('calculate_grades_csv', {}),
|
||||
('get_students_features', {}),
|
||||
('get_enrollment_report', {}),
|
||||
@@ -1045,32 +1038,6 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
|
||||
for enrollment in manual_enrollments:
|
||||
self.assertEqual(enrollment.enrollment.mode, CourseMode.HONOR)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'ALLOW_AUTOMATED_SIGNUPS': True})
|
||||
def test_default_shopping_cart_enrollment_mode_for_white_label(self):
|
||||
"""
|
||||
Test that enrollment mode for white label courses (paid courses) is DEFAULT_SHOPPINGCART_MODE_SLUG.
|
||||
"""
|
||||
# Login white label course instructor
|
||||
self.client.login(username=self.white_label_course_instructor.username, password='test')
|
||||
|
||||
csv_content = b"test_student_wl@example.com,test_student_wl,Test Student,USA"
|
||||
uploaded_file = SimpleUploadedFile("temp.csv", csv_content)
|
||||
response = self.client.post(self.white_label_course_url, {'students_list': uploaded_file})
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
data = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(len(data['row_errors']), 0)
|
||||
self.assertEqual(len(data['warnings']), 0)
|
||||
self.assertEqual(len(data['general_errors']), 0)
|
||||
|
||||
manual_enrollments = ManualEnrollmentAudit.objects.all()
|
||||
self.assertEqual(manual_enrollments.count(), 1)
|
||||
self.assertEqual(manual_enrollments[0].state_transition, UNENROLLED_TO_ENROLLED)
|
||||
|
||||
# Verify enrollment modes to be CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG
|
||||
for enrollment in manual_enrollments:
|
||||
self.assertEqual(enrollment.enrollment.mode, CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
@@ -2595,20 +2562,6 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
self.instructor = InstructorFactory(course_key=self.course.id)
|
||||
CourseDataResearcherRole(self.course.id).add_users(self.instructor)
|
||||
self.client.login(username=self.instructor.username, password='test')
|
||||
self.cart = Order.get_cart_for_user(self.instructor)
|
||||
|
||||
# Create testing invoice 1
|
||||
self.sale_invoice_1 = Invoice.objects.create(
|
||||
total_amount=1234.32, company_name='Test1', company_contact_name='TestName', company_contact_email='Test@company.com',
|
||||
recipient_name='Testw', recipient_email='test1@test.com', customer_reference_number='2Fwe23S',
|
||||
internal_reference="A", course_id=self.course.id, is_valid=True
|
||||
)
|
||||
self.invoice_item = CourseRegistrationCodeInvoiceItem.objects.create(
|
||||
invoice=self.sale_invoice_1,
|
||||
qty=1,
|
||||
unit_price=1234.32,
|
||||
course_id=self.course.id
|
||||
)
|
||||
|
||||
self.students = [UserFactory() for _ in range(6)]
|
||||
for student in self.students:
|
||||
@@ -2620,76 +2573,6 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
email=student.email, course_id=self.course.id
|
||||
)
|
||||
|
||||
def register_with_redemption_code(self, user, code):
|
||||
"""
|
||||
enroll user using a registration code
|
||||
"""
|
||||
redeem_url = reverse('register_code_redemption', args=[code], is_dashboard_endpoint=False)
|
||||
self.client.login(username=user.username, password='test')
|
||||
response = self.client.get(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# check button text
|
||||
self.assertContains(response, 'Activate Course Enrollment')
|
||||
|
||||
response = self.client.post(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_invalidate_sale_record(self):
|
||||
"""
|
||||
Testing the sale invalidating scenario.
|
||||
"""
|
||||
for i in range(2):
|
||||
course_registration_code = CourseRegistrationCode(
|
||||
code='sale_invoice{}'.format(i),
|
||||
course_id=text_type(self.course.id),
|
||||
created_by=self.instructor,
|
||||
invoice=self.sale_invoice_1,
|
||||
invoice_item=self.invoice_item,
|
||||
mode_slug='honor'
|
||||
)
|
||||
course_registration_code.save()
|
||||
|
||||
data = {'invoice_number': self.sale_invoice_1.id, 'event_type': "invalidate"}
|
||||
url = reverse('sale_validation', kwargs={'course_id': text_type(self.course.id)})
|
||||
self.assert_request_status_code(200, url, method="POST", data=data)
|
||||
|
||||
#Now try to fetch data against not existing invoice number
|
||||
test_data_1 = {'invoice_number': 100, 'event_type': "invalidate"}
|
||||
self.assert_request_status_code(404, url, method="POST", data=test_data_1)
|
||||
|
||||
# Now invalidate the same invoice number and expect an Bad request
|
||||
response = self.assert_request_status_code(400, url, method="POST", data=data)
|
||||
self.assertContains(
|
||||
response,
|
||||
"The sale associated with this invoice has already been invalidated.",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
# now re_validate the invoice number
|
||||
data['event_type'] = "re_validate"
|
||||
self.assert_request_status_code(200, url, method="POST", data=data)
|
||||
|
||||
# Now re_validate the same active invoice number and expect an Bad request
|
||||
response = self.assert_request_status_code(400, url, method="POST", data=data)
|
||||
self.assertContains(response, "This invoice is already active.", status_code=400)
|
||||
|
||||
test_data_2 = {'invoice_number': self.sale_invoice_1.id}
|
||||
response = self.assert_request_status_code(400, url, method="POST", data=test_data_2)
|
||||
self.assertContains(response, "Missing required event_type parameter", status_code=400)
|
||||
|
||||
test_data_3 = {'event_type': "re_validate"}
|
||||
response = self.assert_request_status_code(400, url, method="POST", data=test_data_3)
|
||||
self.assertContains(response, "Missing required invoice_number parameter", status_code=400)
|
||||
|
||||
# submitting invalid invoice number
|
||||
data['invoice_number'] = 'testing'
|
||||
response = self.assert_request_status_code(400, url, method="POST", data=data)
|
||||
self.assertContains(
|
||||
response,
|
||||
u"invoice_number must be an integer, {value} provided".format(value=data['invoice_number']),
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
def test_get_problem_responses_invalid_location(self):
|
||||
"""
|
||||
Test whether get_problem_responses returns an appropriate status
|
||||
@@ -2908,7 +2791,6 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
decorated_func(request, text_type(self.course.id))
|
||||
self.assertTrue(func.called)
|
||||
|
||||
|
||||
@patch('lms.djangoapps.instructor.views.api.anonymous_id_for_user', Mock(return_value='42'))
|
||||
@patch('lms.djangoapps.instructor.views.api.unique_id_for_user', Mock(return_value='41'))
|
||||
def test_get_anon_ids(self):
|
||||
|
||||
@@ -28,7 +28,6 @@ from lms.djangoapps.grades.config.waffle import WRITABLE_GRADEBOOK, waffle_flags
|
||||
from lms.djangoapps.instructor.views.gradebook_api import calculate_page_info
|
||||
from openedx.core.djangoapps.site_configuration.models import SiteConfiguration
|
||||
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
|
||||
from shoppingcart.models import CourseRegCodeItem, Order, PaidCourseRegistration
|
||||
from student.models import CourseEnrollment
|
||||
from student.roles import CourseFinanceAdminRole
|
||||
from student.tests.factories import AdminFactory, CourseAccessRoleFactory, CourseEnrollmentFactory
|
||||
@@ -369,15 +368,6 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
|
||||
)
|
||||
self.assertContains(response, 'View Gradebook')
|
||||
|
||||
def test_default_currency_in_the_html_response(self):
|
||||
"""
|
||||
Test that checks the default currency_symbol ($) in the response
|
||||
"""
|
||||
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
|
||||
total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(self.course.id)
|
||||
response = self.client.get(self.url)
|
||||
self.assertContains(response, '${amount}'.format(amount=total_amount))
|
||||
|
||||
def test_course_name_xss(self):
|
||||
"""Test that the instructor dashboard correctly escapes course names
|
||||
with script tags.
|
||||
@@ -385,16 +375,6 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
|
||||
response = self.client.get(self.url)
|
||||
self.assert_no_xss(response, '<script>alert("XSS")</script>')
|
||||
|
||||
@override_settings(PAID_COURSE_REGISTRATION_CURRENCY=['PKR', 'Rs'])
|
||||
def test_override_currency_settings_in_the_html_response(self):
|
||||
"""
|
||||
Test that checks the default currency_symbol ($) in the response
|
||||
"""
|
||||
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
|
||||
total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(self.course.id)
|
||||
response = self.client.get(self.url)
|
||||
self.assertContains(response, '{currency}{amount}'.format(currency='Rs', amount=total_amount))
|
||||
|
||||
@patch.dict(settings.FEATURES, {'DISPLAY_ANALYTICS_ENROLLMENTS': False})
|
||||
@override_settings(ANALYTICS_DASHBOARD_URL='')
|
||||
def test_no_enrollments(self):
|
||||
@@ -481,34 +461,6 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
|
||||
expected_message = self.get_dashboard_analytics_message()
|
||||
self.assertIn(expected_message, response.content.decode(response.charset))
|
||||
|
||||
def add_course_to_user_cart(self, cart, course_key):
|
||||
"""
|
||||
adding course to user cart
|
||||
"""
|
||||
reg_item = PaidCourseRegistration.add_to_order(cart, course_key)
|
||||
return reg_item
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_PAID_COURSE_REGISTRATION': True})
|
||||
def test_total_credit_cart_sales_amount(self):
|
||||
"""
|
||||
Test to check the total amount for all the credit card purchases.
|
||||
"""
|
||||
student = UserFactory.create()
|
||||
self.client.login(username=student.username, password="test")
|
||||
student_cart = Order.get_cart_for_user(student)
|
||||
item = self.add_course_to_user_cart(student_cart, self.course.id)
|
||||
resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {'ItemId': item.id, 'qty': 4})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
student_cart.purchase()
|
||||
|
||||
self.client.login(username=self.instructor.username, password="test")
|
||||
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
|
||||
single_purchase_total = PaidCourseRegistration.get_total_amount_of_purchased_item(self.course.id)
|
||||
bulk_purchase_total = CourseRegCodeItem.get_total_amount_of_purchased_item(self.course.id)
|
||||
total_amount = single_purchase_total + bulk_purchase_total
|
||||
response = self.client.get(self.url)
|
||||
self.assertContains(response, '{currency}{amount}'.format(currency='$', amount=total_amount))
|
||||
|
||||
@ddt.data(
|
||||
(True, True, True),
|
||||
(True, False, False),
|
||||
|
||||
@@ -50,6 +50,7 @@ import instructor_analytics.csvs
|
||||
import instructor_analytics.distributions
|
||||
from bulk_email.api import is_bulk_email_feature_enabled
|
||||
from bulk_email.models import CourseEmail
|
||||
from course_modes.models import CourseMode
|
||||
from edxmako.shortcuts import render_to_string
|
||||
from lms.djangoapps.certificates import api as certs_api
|
||||
from lms.djangoapps.certificates.models import (
|
||||
|
||||
@@ -37,16 +37,6 @@ from lms.djangoapps.instructor_analytics.basic import (
|
||||
sale_record_features
|
||||
)
|
||||
from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory
|
||||
from shoppingcart.models import (
|
||||
Coupon,
|
||||
CouponRedemption,
|
||||
CourseRegCodeItem,
|
||||
CourseRegistrationCode,
|
||||
CourseRegistrationCodeInvoiceItem,
|
||||
Invoice,
|
||||
Order,
|
||||
RegistrationCodeRedemption
|
||||
)
|
||||
from student.models import CourseEnrollment, CourseEnrollmentAllowed
|
||||
from student.roles import CourseSalesAdminRole
|
||||
from student.tests.factories import UserFactory
|
||||
@@ -296,362 +286,3 @@ class TestAnalyticsBasic(ModuleStoreTestCase):
|
||||
self.assertEqual(len(proctored_exam_attempts), 3)
|
||||
for proctored_exam_attempt in proctored_exam_attempts:
|
||||
self.assertEqual(set(proctored_exam_attempt.keys()), set(query_features))
|
||||
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_PAID_COURSE_REGISTRATION': True})
|
||||
class TestCourseSaleRecordsAnalyticsBasic(ModuleStoreTestCase):
|
||||
""" Test basic course sale records analytics functions. """
|
||||
def setUp(self):
|
||||
"""
|
||||
Fixtures.
|
||||
"""
|
||||
super(TestCourseSaleRecordsAnalyticsBasic, self).setUp()
|
||||
self.course = CourseFactory.create()
|
||||
self.cost = 40
|
||||
self.course_mode = CourseMode(
|
||||
course_id=self.course.id, mode_slug="honor",
|
||||
mode_display_name="honor cert", min_price=self.cost
|
||||
)
|
||||
self.course_mode.save()
|
||||
self.instructor = InstructorFactory(course_key=self.course.id)
|
||||
self.client.login(username=self.instructor.username, password='test')
|
||||
|
||||
def test_course_sale_features(self):
|
||||
|
||||
query_features = [
|
||||
'company_name', 'company_contact_name', 'company_contact_email', 'total_codes', 'total_used_codes',
|
||||
'total_amount', 'created', 'customer_reference_number', 'recipient_name', 'recipient_email',
|
||||
'created_by', 'internal_reference', 'invoice_number', 'codes', 'course_id'
|
||||
]
|
||||
|
||||
#create invoice
|
||||
sale_invoice = Invoice.objects.create(
|
||||
total_amount=1234.32, company_name='Test1', company_contact_name='TestName',
|
||||
company_contact_email='test@company.com', recipient_name='Testw_1', recipient_email='test2@test.com',
|
||||
customer_reference_number='2Fwe23S', internal_reference="ABC", course_id=self.course.id
|
||||
)
|
||||
invoice_item = CourseRegistrationCodeInvoiceItem.objects.create(
|
||||
invoice=sale_invoice,
|
||||
qty=1,
|
||||
unit_price=1234.32,
|
||||
course_id=self.course.id
|
||||
)
|
||||
for i in range(5):
|
||||
course_code = CourseRegistrationCode(
|
||||
code="test_code{}".format(i), course_id=text_type(self.course.id),
|
||||
created_by=self.instructor, invoice=sale_invoice, invoice_item=invoice_item, mode_slug='honor'
|
||||
)
|
||||
course_code.save()
|
||||
|
||||
course_sale_records_list = sale_record_features(self.course.id, query_features)
|
||||
|
||||
for sale_record in course_sale_records_list:
|
||||
self.assertEqual(sale_record['total_amount'], sale_invoice.total_amount)
|
||||
self.assertEqual(sale_record['recipient_email'], sale_invoice.recipient_email)
|
||||
self.assertEqual(sale_record['recipient_name'], sale_invoice.recipient_name)
|
||||
self.assertEqual(sale_record['company_name'], sale_invoice.company_name)
|
||||
self.assertEqual(sale_record['company_contact_name'], sale_invoice.company_contact_name)
|
||||
self.assertEqual(sale_record['company_contact_email'], sale_invoice.company_contact_email)
|
||||
self.assertEqual(sale_record['internal_reference'], sale_invoice.internal_reference)
|
||||
self.assertEqual(sale_record['customer_reference_number'], sale_invoice.customer_reference_number)
|
||||
self.assertEqual(sale_record['invoice_number'], sale_invoice.id)
|
||||
self.assertEqual(sale_record['created_by'], self.instructor)
|
||||
self.assertEqual(sale_record['total_used_codes'], 0)
|
||||
self.assertEqual(sale_record['total_codes'], 5)
|
||||
|
||||
def test_course_sale_no_codes(self):
|
||||
|
||||
query_features = [
|
||||
'company_name', 'company_contact_name', 'company_contact_email', 'total_codes', 'total_used_codes',
|
||||
'total_amount', 'created', 'customer_reference_number', 'recipient_name', 'recipient_email',
|
||||
'created_by', 'internal_reference', 'invoice_number', 'codes', 'course_id'
|
||||
]
|
||||
|
||||
#create invoice
|
||||
sale_invoice = Invoice.objects.create(
|
||||
total_amount=0.00, company_name='Test1', company_contact_name='TestName',
|
||||
company_contact_email='test@company.com', recipient_name='Testw_1', recipient_email='test2@test.com',
|
||||
customer_reference_number='2Fwe23S', internal_reference="ABC", course_id=self.course.id
|
||||
)
|
||||
CourseRegistrationCodeInvoiceItem.objects.create(
|
||||
invoice=sale_invoice,
|
||||
qty=0,
|
||||
unit_price=0.00,
|
||||
course_id=self.course.id
|
||||
)
|
||||
|
||||
course_sale_records_list = sale_record_features(self.course.id, query_features)
|
||||
|
||||
for sale_record in course_sale_records_list:
|
||||
self.assertEqual(sale_record['total_amount'], sale_invoice.total_amount)
|
||||
self.assertEqual(sale_record['recipient_email'], sale_invoice.recipient_email)
|
||||
self.assertEqual(sale_record['recipient_name'], sale_invoice.recipient_name)
|
||||
self.assertEqual(sale_record['company_name'], sale_invoice.company_name)
|
||||
self.assertEqual(sale_record['company_contact_name'], sale_invoice.company_contact_name)
|
||||
self.assertEqual(sale_record['company_contact_email'], sale_invoice.company_contact_email)
|
||||
self.assertEqual(sale_record['internal_reference'], sale_invoice.internal_reference)
|
||||
self.assertEqual(sale_record['customer_reference_number'], sale_invoice.customer_reference_number)
|
||||
self.assertEqual(sale_record['invoice_number'], sale_invoice.id)
|
||||
self.assertEqual(sale_record['created_by'], None)
|
||||
self.assertEqual(sale_record['total_used_codes'], 0)
|
||||
self.assertEqual(sale_record['total_codes'], 0)
|
||||
|
||||
def test_sale_order_features_with_discount(self):
|
||||
"""
|
||||
Test Order Sales Report CSV
|
||||
"""
|
||||
query_features = [
|
||||
('id', 'Order Id'),
|
||||
('company_name', 'Company Name'),
|
||||
('company_contact_name', 'Company Contact Name'),
|
||||
('company_contact_email', 'Company Contact Email'),
|
||||
('total_amount', 'Total Amount'),
|
||||
('total_codes', 'Total Codes'),
|
||||
('total_used_codes', 'Total Used Codes'),
|
||||
('logged_in_username', 'Login Username'),
|
||||
('logged_in_email', 'Login User Email'),
|
||||
('purchase_time', 'Date of Sale'),
|
||||
('customer_reference_number', 'Customer Reference Number'),
|
||||
('recipient_name', 'Recipient Name'),
|
||||
('recipient_email', 'Recipient Email'),
|
||||
('bill_to_street1', 'Street 1'),
|
||||
('bill_to_street2', 'Street 2'),
|
||||
('bill_to_city', 'City'),
|
||||
('bill_to_state', 'State'),
|
||||
('bill_to_postalcode', 'Postal Code'),
|
||||
('bill_to_country', 'Country'),
|
||||
('order_type', 'Order Type'),
|
||||
('status', 'Order Item Status'),
|
||||
('coupon_code', 'Coupon Code'),
|
||||
('unit_cost', 'Unit Price'),
|
||||
('list_price', 'List Price'),
|
||||
('codes', 'Registration Codes'),
|
||||
('course_id', 'Course Id')
|
||||
]
|
||||
# add the coupon code for the course
|
||||
coupon = Coupon(
|
||||
code='test_code',
|
||||
description='test_description',
|
||||
course_id=self.course.id,
|
||||
percentage_discount='10',
|
||||
created_by=self.instructor,
|
||||
is_active=True
|
||||
)
|
||||
coupon.save()
|
||||
order = Order.get_cart_for_user(self.instructor)
|
||||
order.order_type = 'business'
|
||||
order.save()
|
||||
order.add_billing_details(
|
||||
company_name='Test Company',
|
||||
company_contact_name='Test',
|
||||
company_contact_email='test@123',
|
||||
recipient_name='R1', recipient_email='',
|
||||
customer_reference_number='PO#23'
|
||||
)
|
||||
CourseRegCodeItem.add_to_order(order, self.course.id, 4)
|
||||
# apply the coupon code to the item in the cart
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': coupon.code})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
order.purchase()
|
||||
|
||||
# get the updated item
|
||||
item = order.orderitem_set.all().select_subclasses()[0]
|
||||
# get the redeemed coupon information
|
||||
coupon_redemption = CouponRedemption.objects.select_related('coupon').filter(order=order)
|
||||
|
||||
db_columns = [x[0] for x in query_features]
|
||||
sale_order_records_list = sale_order_record_features(self.course.id, db_columns)
|
||||
|
||||
for sale_order_record in sale_order_records_list:
|
||||
self.assertEqual(sale_order_record['recipient_email'], order.recipient_email)
|
||||
self.assertEqual(sale_order_record['recipient_name'], order.recipient_name)
|
||||
self.assertEqual(sale_order_record['company_name'], order.company_name)
|
||||
self.assertEqual(sale_order_record['company_contact_name'], order.company_contact_name)
|
||||
self.assertEqual(sale_order_record['company_contact_email'], order.company_contact_email)
|
||||
self.assertEqual(sale_order_record['customer_reference_number'], order.customer_reference_number)
|
||||
self.assertEqual(sale_order_record['unit_cost'], item.unit_cost)
|
||||
self.assertEqual(sale_order_record['list_price'], item.list_price)
|
||||
self.assertEqual(sale_order_record['status'], item.status)
|
||||
self.assertEqual(sale_order_record['coupon_code'], coupon_redemption[0].coupon.code)
|
||||
|
||||
def test_sale_order_features_without_discount(self):
|
||||
"""
|
||||
Test Order Sales Report CSV
|
||||
"""
|
||||
query_features = [
|
||||
('id', 'Order Id'),
|
||||
('company_name', 'Company Name'),
|
||||
('company_contact_name', 'Company Contact Name'),
|
||||
('company_contact_email', 'Company Contact Email'),
|
||||
('total_amount', 'Total Amount'),
|
||||
('total_codes', 'Total Codes'),
|
||||
('total_used_codes', 'Total Used Codes'),
|
||||
('logged_in_username', 'Login Username'),
|
||||
('logged_in_email', 'Login User Email'),
|
||||
('purchase_time', 'Date of Sale'),
|
||||
('customer_reference_number', 'Customer Reference Number'),
|
||||
('recipient_name', 'Recipient Name'),
|
||||
('recipient_email', 'Recipient Email'),
|
||||
('bill_to_street1', 'Street 1'),
|
||||
('bill_to_street2', 'Street 2'),
|
||||
('bill_to_city', 'City'),
|
||||
('bill_to_state', 'State'),
|
||||
('bill_to_postalcode', 'Postal Code'),
|
||||
('bill_to_country', 'Country'),
|
||||
('order_type', 'Order Type'),
|
||||
('status', 'Order Item Status'),
|
||||
('coupon_code', 'Coupon Code'),
|
||||
('unit_cost', 'Unit Price'),
|
||||
('list_price', 'List Price'),
|
||||
('codes', 'Registration Codes'),
|
||||
('course_id', 'Course Id'),
|
||||
('quantity', 'Quantity'),
|
||||
('total_discount', 'Total Discount'),
|
||||
('total_amount', 'Total Amount Paid'),
|
||||
]
|
||||
# add the coupon code for the course
|
||||
order = Order.get_cart_for_user(self.instructor)
|
||||
order.order_type = 'business'
|
||||
order.save()
|
||||
order.add_billing_details(
|
||||
company_name='Test Company',
|
||||
company_contact_name='Test',
|
||||
company_contact_email='test@123',
|
||||
recipient_name='R1', recipient_email='',
|
||||
customer_reference_number='PO#23'
|
||||
)
|
||||
CourseRegCodeItem.add_to_order(order, self.course.id, 4)
|
||||
order.purchase()
|
||||
|
||||
# get the updated item
|
||||
item = order.orderitem_set.all().select_subclasses()[0]
|
||||
|
||||
db_columns = [x[0] for x in query_features]
|
||||
sale_order_records_list = sale_order_record_features(self.course.id, db_columns)
|
||||
|
||||
for sale_order_record in sale_order_records_list:
|
||||
self.assertEqual(sale_order_record['recipient_email'], order.recipient_email)
|
||||
self.assertEqual(sale_order_record['recipient_name'], order.recipient_name)
|
||||
self.assertEqual(sale_order_record['company_name'], order.company_name)
|
||||
self.assertEqual(sale_order_record['company_contact_name'], order.company_contact_name)
|
||||
self.assertEqual(sale_order_record['company_contact_email'], order.company_contact_email)
|
||||
self.assertEqual(sale_order_record['customer_reference_number'], order.customer_reference_number)
|
||||
self.assertEqual(sale_order_record['unit_cost'], item.unit_cost)
|
||||
# Make sure list price is not None and matches the unit price since no discount was applied.
|
||||
self.assertIsNotNone(sale_order_record['list_price'])
|
||||
self.assertEqual(sale_order_record['list_price'], item.unit_cost)
|
||||
self.assertEqual(sale_order_record['status'], item.status)
|
||||
self.assertEqual(sale_order_record['coupon_code'], 'N/A')
|
||||
self.assertEqual(sale_order_record['total_amount'], item.unit_cost * item.qty)
|
||||
self.assertEqual(sale_order_record['total_discount'], 0)
|
||||
self.assertEqual(sale_order_record['quantity'], item.qty)
|
||||
|
||||
|
||||
class TestCourseRegistrationCodeAnalyticsBasic(ModuleStoreTestCase):
|
||||
""" Test basic course registration codes analytics functions. """
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Fixtures.
|
||||
"""
|
||||
super(TestCourseRegistrationCodeAnalyticsBasic, self).setUp()
|
||||
self.course = CourseFactory.create()
|
||||
self.instructor = InstructorFactory(course_key=self.course.id)
|
||||
self.client.login(username=self.instructor.username, password='test')
|
||||
CourseSalesAdminRole(self.course.id).add_users(self.instructor)
|
||||
|
||||
# Create a paid course mode.
|
||||
mode = CourseModeFactory.create(course_id=self.course.id, min_price=1)
|
||||
|
||||
url = reverse('generate_registration_codes',
|
||||
kwargs={'course_id': text_type(self.course.id)})
|
||||
|
||||
data = {
|
||||
'total_registration_codes': 12, 'company_name': 'Test Group', 'unit_price': 122.45,
|
||||
'company_contact_name': 'TestName', 'company_contact_email': 'test@company.com', 'recipient_name': 'Test123',
|
||||
'recipient_email': 'test@123.com', 'address_line_1': 'Portland Street', 'address_line_2': '',
|
||||
'address_line_3': '', 'city': '', 'state': '', 'zip': '', 'country': '',
|
||||
'customer_reference_number': '123A23F', 'internal_reference': '', 'invoice': ''
|
||||
}
|
||||
|
||||
response = self.client.post(url, data, **{'HTTP_HOST': 'localhost'})
|
||||
self.assertEqual(response.status_code, 200, response.content)
|
||||
|
||||
def test_course_registration_features(self):
|
||||
query_features = [
|
||||
'code', 'redeem_code_url', 'course_id', 'company_name', 'created_by',
|
||||
'redeemed_by', 'invoice_id', 'purchaser', 'customer_reference_number', 'internal_reference'
|
||||
]
|
||||
order = Order(user=self.instructor, status='purchased')
|
||||
order.save()
|
||||
|
||||
registration_code_redemption = RegistrationCodeRedemption(
|
||||
registration_code_id=1, redeemed_by=self.instructor
|
||||
)
|
||||
registration_code_redemption.save()
|
||||
registration_codes = CourseRegistrationCode.objects.all()
|
||||
course_registration_list = course_registration_features(query_features, registration_codes, csv_type='download')
|
||||
self.assertEqual(len(course_registration_list), len(registration_codes))
|
||||
for course_registration in course_registration_list:
|
||||
self.assertEqual(set(course_registration.keys()), set(query_features))
|
||||
self.assertIn(course_registration['code'], [registration_code.code for registration_code in registration_codes])
|
||||
self.assertIn(
|
||||
course_registration['course_id'],
|
||||
[text_type(registration_code.course_id) for registration_code in registration_codes]
|
||||
)
|
||||
self.assertIn(
|
||||
course_registration['company_name'],
|
||||
[
|
||||
registration_code.invoice_item.invoice.company_name
|
||||
for registration_code in registration_codes
|
||||
]
|
||||
)
|
||||
self.assertIn(
|
||||
course_registration['invoice_id'],
|
||||
[
|
||||
registration_code.invoice_item.invoice_id
|
||||
for registration_code in registration_codes
|
||||
]
|
||||
)
|
||||
|
||||
def test_coupon_codes_features(self):
|
||||
query_features = [
|
||||
'course_id', 'percentage_discount', 'code_redeemed_count', 'description', 'expiration_date',
|
||||
'total_discounted_amount', 'total_discounted_seats'
|
||||
]
|
||||
for i in range(10):
|
||||
coupon = Coupon(
|
||||
code='test_code{0}'.format(i),
|
||||
description='test_description',
|
||||
course_id=self.course.id, percentage_discount='{0}'.format(i),
|
||||
created_by=self.instructor,
|
||||
is_active=True
|
||||
)
|
||||
coupon.save()
|
||||
#now create coupons with the expiration dates
|
||||
for i in range(5):
|
||||
coupon = Coupon(
|
||||
code='coupon{0}'.format(i), description='test_description', course_id=self.course.id,
|
||||
percentage_discount='{0}'.format(i), created_by=self.instructor, is_active=True,
|
||||
expiration_date=datetime.datetime.now(pytz.UTC) + datetime.timedelta(days=2)
|
||||
)
|
||||
coupon.save()
|
||||
|
||||
active_coupons = Coupon.objects.filter(
|
||||
Q(course_id=self.course.id),
|
||||
Q(is_active=True),
|
||||
Q(expiration_date__gt=datetime.datetime.now(pytz.UTC)) |
|
||||
Q(expiration_date__isnull=True)
|
||||
)
|
||||
active_coupons_list = coupon_codes_features(query_features, active_coupons, self.course.id)
|
||||
self.assertEqual(len(active_coupons_list), len(active_coupons))
|
||||
for active_coupon in active_coupons_list:
|
||||
self.assertEqual(set(active_coupon.keys()), set(query_features))
|
||||
self.assertIn(active_coupon['percentage_discount'], [coupon.percentage_discount for coupon in active_coupons])
|
||||
self.assertIn(active_coupon['description'], [coupon.description for coupon in active_coupons])
|
||||
if active_coupon['expiration_date']:
|
||||
self.assertIn(active_coupon['expiration_date'], [coupon.display_expiry_date for coupon in active_coupons])
|
||||
self.assertIn(
|
||||
active_coupon['course_id'],
|
||||
[text_type(coupon.course_id) for coupon in active_coupons]
|
||||
)
|
||||
|
||||
@@ -73,15 +73,6 @@ from openedx.core.djangoapps.credit.tests.factories import CreditCourseFactory
|
||||
from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme
|
||||
from openedx.core.djangoapps.util.testing import ContentGroupTestCase, TestConditionalContent
|
||||
from openedx.core.lib.teams_config import TeamsConfig
|
||||
from shoppingcart.models import (
|
||||
Coupon,
|
||||
CourseRegistrationCode,
|
||||
CourseRegistrationCodeInvoiceItem,
|
||||
Invoice,
|
||||
InvoiceTransaction,
|
||||
Order,
|
||||
PaidCourseRegistration
|
||||
)
|
||||
from student.models import ALLOWEDTOENROLL_TO_ENROLLED, CourseEnrollment, CourseEnrollmentAllowed, ManualEnrollmentAudit
|
||||
from student.tests.factories import CourseEnrollmentFactory, UserFactory
|
||||
from survey.models import SurveyAnswer, SurveyForm
|
||||
@@ -668,209 +659,6 @@ class TestProblemResponsesReport(TestReportMixin, InstructorTaskModuleTestCase):
|
||||
self.assertIn("report_name", result)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_PAID_COURSE_REGISTRATION': True})
|
||||
class TestInstructorDetailedEnrollmentReport(TestReportMixin, InstructorTaskCourseTestCase):
|
||||
"""
|
||||
Tests that CSV detailed enrollment generation works.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(TestInstructorDetailedEnrollmentReport, self).setUp()
|
||||
self.course = CourseFactory.create()
|
||||
CourseModeFactory.create(
|
||||
course_id=self.course.id,
|
||||
min_price=50,
|
||||
mode_slug=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG
|
||||
)
|
||||
|
||||
# create testing invoice 1
|
||||
self.instructor = InstructorFactory(course_key=self.course.id)
|
||||
self.sale_invoice_1 = Invoice.objects.create(
|
||||
total_amount=1234.32, company_name='Test1', company_contact_name='TestName',
|
||||
company_contact_email='Test@company.com',
|
||||
recipient_name='Testw', recipient_email='test1@test.com', customer_reference_number='2Fwe23S',
|
||||
internal_reference="A", course_id=self.course.id, is_valid=True
|
||||
)
|
||||
self.invoice_item = CourseRegistrationCodeInvoiceItem.objects.create(
|
||||
invoice=self.sale_invoice_1,
|
||||
qty=1,
|
||||
unit_price=1234.32,
|
||||
course_id=self.course.id
|
||||
)
|
||||
|
||||
def test_success(self):
|
||||
self.create_student('student', 'student@example.com')
|
||||
task_input = {'features': []}
|
||||
with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'):
|
||||
result = upload_enrollment_report(None, None, self.course.id, task_input, 'generating_enrollment_report')
|
||||
|
||||
self.assertDictContainsSubset({'attempted': 1, 'succeeded': 1, 'failed': 0}, result)
|
||||
|
||||
def test_student_paid_course_enrollment_report(self):
|
||||
"""
|
||||
test to check the paid user enrollment csv report status
|
||||
and enrollment source.
|
||||
"""
|
||||
student = UserFactory()
|
||||
student_cart = Order.get_cart_for_user(student)
|
||||
PaidCourseRegistration.add_to_order(student_cart, self.course.id)
|
||||
student_cart.purchase()
|
||||
|
||||
task_input = {'features': []}
|
||||
with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'):
|
||||
result = upload_enrollment_report(None, None, self.course.id, task_input, 'generating_enrollment_report')
|
||||
self.assertDictContainsSubset({'attempted': 1, 'succeeded': 1, 'failed': 0}, result)
|
||||
self._verify_cell_data_in_csv(student.username, 'Enrollment Source', 'Credit Card - Individual')
|
||||
self._verify_cell_data_in_csv(student.username, 'Payment Status', 'purchased')
|
||||
|
||||
def test_student_manually_enrolled_in_detailed_enrollment_source(self):
|
||||
"""
|
||||
test to check the manually enrolled user enrollment report status
|
||||
and enrollment source.
|
||||
"""
|
||||
student = UserFactory()
|
||||
enrollment = CourseEnrollment.enroll(student, self.course.id)
|
||||
ManualEnrollmentAudit.create_manual_enrollment_audit(
|
||||
self.instructor, student.email, ALLOWEDTOENROLL_TO_ENROLLED,
|
||||
'manually enrolling unenrolled user', enrollment
|
||||
)
|
||||
|
||||
task_input = {'features': []}
|
||||
with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'):
|
||||
result = upload_enrollment_report(None, None, self.course.id, task_input, 'generating_enrollment_report')
|
||||
|
||||
enrollment_source = u'manually enrolled by username: {username}'.format(
|
||||
username=self.instructor.username)
|
||||
self.assertDictContainsSubset({'attempted': 1, 'succeeded': 1, 'failed': 0}, result)
|
||||
self._verify_cell_data_in_csv(student.username, 'Enrollment Source', enrollment_source)
|
||||
self._verify_cell_data_in_csv(
|
||||
student.username,
|
||||
'Manual (Un)Enrollment Reason',
|
||||
'manually enrolling unenrolled user'
|
||||
)
|
||||
self._verify_cell_data_in_csv(student.username, 'Payment Status', 'TBD')
|
||||
|
||||
def test_student_used_enrollment_code_for_course_enrollment(self):
|
||||
"""
|
||||
test to check the user enrollment source and payment status in the
|
||||
enrollment detailed report
|
||||
"""
|
||||
student = UserFactory()
|
||||
self.client.login(username=student.username, password='test')
|
||||
student_cart = Order.get_cart_for_user(student)
|
||||
paid_course_reg_item = PaidCourseRegistration.add_to_order(student_cart, self.course.id)
|
||||
# update the quantity of the cart item paid_course_reg_item
|
||||
resp = self.client.post(reverse('shoppingcart.views.update_user_cart'),
|
||||
{'ItemId': paid_course_reg_item.id, 'qty': '4'})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
student_cart.purchase()
|
||||
|
||||
course_reg_codes = CourseRegistrationCode.objects.filter(order=student_cart)
|
||||
redeem_url = reverse('register_code_redemption', args=[course_reg_codes[0].code])
|
||||
response = self.client.get(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# check button text
|
||||
self.assertContains(response, 'Activate Course Enrollment')
|
||||
|
||||
response = self.client.post(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
task_input = {'features': []}
|
||||
with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'):
|
||||
result = upload_enrollment_report(None, None, self.course.id, task_input, 'generating_enrollment_report')
|
||||
self.assertDictContainsSubset({'attempted': 1, 'succeeded': 1, 'failed': 0}, result)
|
||||
self._verify_cell_data_in_csv(student.username, 'Enrollment Source', 'Used Registration Code')
|
||||
self._verify_cell_data_in_csv(student.username, 'Payment Status', 'purchased')
|
||||
|
||||
def test_student_used_invoice_unpaid_enrollment_code_for_course_enrollment(self):
|
||||
"""
|
||||
test to check the user enrollment source and payment status in the
|
||||
enrollment detailed report
|
||||
"""
|
||||
student = UserFactory()
|
||||
self.client.login(username=student.username, password='test')
|
||||
|
||||
course_registration_code = CourseRegistrationCode(
|
||||
code='abcde',
|
||||
course_id=text_type(self.course.id),
|
||||
created_by=self.instructor,
|
||||
invoice=self.sale_invoice_1,
|
||||
invoice_item=self.invoice_item,
|
||||
mode_slug=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG
|
||||
)
|
||||
course_registration_code.save()
|
||||
|
||||
redeem_url = reverse('register_code_redemption', args=['abcde'])
|
||||
response = self.client.get(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# check button text
|
||||
self.assertContains(response, 'Activate Course Enrollment')
|
||||
|
||||
response = self.client.post(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
task_input = {'features': []}
|
||||
with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'):
|
||||
result = upload_enrollment_report(None, None, self.course.id, task_input, 'generating_enrollment_report')
|
||||
self.assertDictContainsSubset({'attempted': 1, 'succeeded': 1, 'failed': 0}, result)
|
||||
self._verify_cell_data_in_csv(student.username, 'Enrollment Source', 'Used Registration Code')
|
||||
self._verify_cell_data_in_csv(student.username, 'Payment Status', 'Invoice Outstanding')
|
||||
|
||||
def test_student_used_invoice_paid_enrollment_code_for_course_enrollment(self):
|
||||
"""
|
||||
test to check the user enrollment source and payment status in the
|
||||
enrollment detailed report
|
||||
"""
|
||||
student = UserFactory()
|
||||
self.client.login(username=student.username, password='test')
|
||||
invoice_transaction = InvoiceTransaction(
|
||||
invoice=self.sale_invoice_1,
|
||||
amount=self.sale_invoice_1.total_amount,
|
||||
status='completed',
|
||||
created_by=self.instructor,
|
||||
last_modified_by=self.instructor
|
||||
)
|
||||
invoice_transaction.save()
|
||||
course_registration_code = CourseRegistrationCode(
|
||||
code='abcde',
|
||||
course_id=text_type(self.course.id),
|
||||
created_by=self.instructor,
|
||||
invoice=self.sale_invoice_1,
|
||||
invoice_item=self.invoice_item,
|
||||
mode_slug=CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG
|
||||
)
|
||||
course_registration_code.save()
|
||||
|
||||
redeem_url = reverse('register_code_redemption', args=['abcde'])
|
||||
response = self.client.get(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# check button text
|
||||
self.assertContains(response, 'Activate Course Enrollment')
|
||||
|
||||
response = self.client.post(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
task_input = {'features': []}
|
||||
with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'):
|
||||
result = upload_enrollment_report(None, None, self.course.id, task_input, 'generating_enrollment_report')
|
||||
self.assertDictContainsSubset({'attempted': 1, 'succeeded': 1, 'failed': 0}, result)
|
||||
self._verify_cell_data_in_csv(student.username, 'Enrollment Source', 'Used Registration Code')
|
||||
self._verify_cell_data_in_csv(student.username, 'Payment Status', 'Invoice Paid')
|
||||
|
||||
def _verify_cell_data_in_csv(self, username, column_header, expected_cell_content):
|
||||
"""
|
||||
Verify that the last ReportStore CSV contains the expected content.
|
||||
"""
|
||||
report_store = ReportStore.from_config(config_name='FINANCIAL_REPORTS')
|
||||
report_csv_filename = report_store.links_for(self.course.id)[0][0]
|
||||
report_path = report_store.path_to(self.course.id, report_csv_filename)
|
||||
with report_store.storage.open(report_path) as csv_file:
|
||||
# Expand the dict reader generator so we don't lose it's content
|
||||
for row in unicodecsv.DictReader(csv_file):
|
||||
if row.get('Username') == username:
|
||||
self.assertEqual(row[column_header], expected_cell_content)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestProblemGradeReport(TestReportMixin, InstructorTaskModuleTestCase):
|
||||
"""
|
||||
@@ -1258,34 +1046,6 @@ class TestExecutiveSummaryReport(TestReportMixin, InstructorTaskCourseTestCase):
|
||||
self.instructor = InstructorFactory(course_key=self.course.id)
|
||||
self.student1 = UserFactory()
|
||||
self.student2 = UserFactory()
|
||||
self.student1_cart = Order.get_cart_for_user(self.student1)
|
||||
self.student2_cart = Order.get_cart_for_user(self.student2)
|
||||
|
||||
self.sale_invoice_1 = Invoice.objects.create(
|
||||
total_amount=1234.32, company_name='Test1', company_contact_name='TestName',
|
||||
company_contact_email='Test@company.com',
|
||||
recipient_name='Testw', recipient_email='test1@test.com', customer_reference_number='2Fwe23S',
|
||||
internal_reference="A", course_id=self.course.id, is_valid=True
|
||||
)
|
||||
InvoiceTransaction.objects.create(
|
||||
invoice=self.sale_invoice_1,
|
||||
amount=self.sale_invoice_1.total_amount,
|
||||
status='completed',
|
||||
created_by=self.instructor,
|
||||
last_modified_by=self.instructor
|
||||
)
|
||||
self.invoice_item = CourseRegistrationCodeInvoiceItem.objects.create(
|
||||
invoice=self.sale_invoice_1,
|
||||
qty=10,
|
||||
unit_price=1234.32,
|
||||
course_id=self.course.id
|
||||
)
|
||||
for i in range(5):
|
||||
coupon = Coupon(
|
||||
code='coupon{0}'.format(i), description='test_description', course_id=self.course.id,
|
||||
percentage_discount='{0}'.format(i), created_by=self.instructor, is_active=True,
|
||||
)
|
||||
coupon.save()
|
||||
|
||||
def test_successfully_generate_executive_summary_report(self):
|
||||
"""
|
||||
@@ -1300,66 +1060,6 @@ class TestExecutiveSummaryReport(TestReportMixin, InstructorTaskCourseTestCase):
|
||||
ReportStore.from_config(config_name='FINANCIAL_REPORTS')
|
||||
self.assertDictContainsSubset({'attempted': 1, 'succeeded': 1, 'failed': 0}, result)
|
||||
|
||||
def students_purchases(self):
|
||||
"""
|
||||
Students purchases the courses using enrollment
|
||||
and coupon codes.
|
||||
"""
|
||||
self.client.login(username=self.student1.username, password='test')
|
||||
paid_course_reg_item = PaidCourseRegistration.add_to_order(self.student1_cart, self.course.id)
|
||||
# update the quantity of the cart item paid_course_reg_item
|
||||
resp = self.client.post(reverse('shoppingcart.views.update_user_cart'), {
|
||||
'ItemId': paid_course_reg_item.id, 'qty': '4'
|
||||
})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
# apply the coupon code to the item in the cart
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': 'coupon1'})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
self.student1_cart.purchase()
|
||||
|
||||
course_reg_codes = CourseRegistrationCode.objects.filter(order=self.student1_cart)
|
||||
redeem_url = reverse('register_code_redemption', args=[course_reg_codes[0].code])
|
||||
response = self.client.get(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# check button text
|
||||
self.assertContains(response, 'Activate Course Enrollment')
|
||||
|
||||
response = self.client.post(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.client.login(username=self.student2.username, password='test')
|
||||
PaidCourseRegistration.add_to_order(self.student2_cart, self.course.id)
|
||||
|
||||
# apply the coupon code to the item in the cart
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': 'coupon1'})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
self.student2_cart.purchase()
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_PAID_COURSE_REGISTRATION': True})
|
||||
def test_generate_executive_summary_report(self):
|
||||
"""
|
||||
test to generate executive summary report
|
||||
and then test the report authenticity.
|
||||
"""
|
||||
self.students_purchases()
|
||||
task_input = {'features': []}
|
||||
with patch('lms.djangoapps.instructor_task.tasks_helper.runner._get_current_task'):
|
||||
result = upload_exec_summary_report(
|
||||
None, None, self.course.id,
|
||||
task_input, 'generating executive summary report'
|
||||
)
|
||||
report_store = ReportStore.from_config(config_name='FINANCIAL_REPORTS')
|
||||
expected_data = [
|
||||
'Gross Revenue Collected', '$1481.82',
|
||||
'Gross Revenue Pending', '$0.00',
|
||||
'Average Price per Seat', '$296.36',
|
||||
'Number of seats purchased using coupon codes', '<td>2</td>'
|
||||
]
|
||||
self.assertDictContainsSubset({'attempted': 1, 'succeeded': 1, 'failed': 0}, result)
|
||||
self._verify_html_file_report(report_store, expected_data)
|
||||
|
||||
def _verify_html_file_report(self, report_store, expected_data):
|
||||
"""
|
||||
Verify grade report data.
|
||||
|
||||
@@ -491,353 +491,6 @@ class OrderItemTest(TestCase):
|
||||
self.assertEqual(item.get_list_price(), item.list_price)
|
||||
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_PAID_COURSE_REGISTRATION': True})
|
||||
class PaidCourseRegistrationTest(ModuleStoreTestCase):
|
||||
"""
|
||||
Paid Course Registration Tests.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(PaidCourseRegistrationTest, self).setUp()
|
||||
|
||||
self.user = UserFactory.create()
|
||||
self.user.set_password('password')
|
||||
self.user.save()
|
||||
self.cost = 40
|
||||
self.course = CourseFactory.create()
|
||||
self.course_key = self.course.id
|
||||
self.course_mode = CourseMode(
|
||||
course_id=self.course_key,
|
||||
mode_slug=CourseMode.HONOR,
|
||||
mode_display_name="honor cert",
|
||||
min_price=self.cost
|
||||
)
|
||||
self.course_mode.save()
|
||||
self.percentage_discount = 20.0
|
||||
self.cart = Order.get_cart_for_user(self.user)
|
||||
|
||||
def test_get_total_amount_of_purchased_items(self):
|
||||
"""
|
||||
Test to check the total amount of the
|
||||
purchased items.
|
||||
"""
|
||||
PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug=CourseMode.HONOR)
|
||||
self.cart.purchase()
|
||||
|
||||
total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(course_key=self.course_key)
|
||||
self.assertEqual(total_amount, 40.00)
|
||||
|
||||
def test_get_total_amount_empty(self):
|
||||
"""
|
||||
Test to check the total amount of the
|
||||
purchased items.
|
||||
"""
|
||||
total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(course_key=self.course_key)
|
||||
self.assertEqual(total_amount, 0.00)
|
||||
|
||||
def test_add_to_order(self):
|
||||
reg1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug=CourseMode.HONOR)
|
||||
|
||||
self.assertEqual(reg1.unit_cost, self.cost)
|
||||
self.assertEqual(reg1.line_cost, self.cost)
|
||||
self.assertEqual(reg1.unit_cost, self.course_mode.min_price)
|
||||
self.assertEqual(reg1.mode, "honor")
|
||||
self.assertEqual(reg1.user, self.user)
|
||||
self.assertEqual(reg1.status, "cart")
|
||||
self.assertTrue(PaidCourseRegistration.contained_in_order(self.cart, self.course_key))
|
||||
self.assertFalse(PaidCourseRegistration.contained_in_order(
|
||||
self.cart, CourseLocator(org="MITx", course="999", run="Robot_Super_Course_abcd"))
|
||||
)
|
||||
|
||||
self.assertEqual(self.cart.total_cost, self.cost)
|
||||
|
||||
def test_order_generated_registration_codes(self):
|
||||
"""
|
||||
Test to check for the order generated registration
|
||||
codes.
|
||||
"""
|
||||
self.cart.order_type = 'business'
|
||||
self.cart.save()
|
||||
item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
|
||||
self.cart.purchase()
|
||||
registration_codes = CourseRegistrationCode.order_generated_registration_codes(self.course_key)
|
||||
self.assertEqual(registration_codes.count(), item.qty)
|
||||
|
||||
def test_order_generated_totals(self):
|
||||
"""
|
||||
Test to check for the order generated registration
|
||||
codes.
|
||||
"""
|
||||
|
||||
total_amount = CourseRegCodeItem.get_total_amount_of_purchased_item(self.course_key)
|
||||
self.assertEqual(total_amount, 0)
|
||||
|
||||
self.cart.order_type = 'business'
|
||||
self.cart.save()
|
||||
item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2, mode_slug=CourseMode.HONOR)
|
||||
self.cart.purchase()
|
||||
registration_codes = CourseRegistrationCode.order_generated_registration_codes(self.course_key)
|
||||
self.assertEqual(registration_codes.count(), item.qty)
|
||||
|
||||
total_amount = CourseRegCodeItem.get_total_amount_of_purchased_item(self.course_key)
|
||||
self.assertEqual(total_amount, 80.00)
|
||||
|
||||
def add_coupon(self, course_key, is_active, code):
|
||||
"""
|
||||
add dummy coupon into models
|
||||
"""
|
||||
Coupon.objects.create(
|
||||
code=code,
|
||||
description='testing code',
|
||||
course_id=course_key,
|
||||
percentage_discount=self.percentage_discount,
|
||||
created_by=self.user,
|
||||
is_active=is_active
|
||||
)
|
||||
|
||||
def login_user(self, username):
|
||||
"""
|
||||
login the user to the platform.
|
||||
"""
|
||||
self.client.login(username=username, password="password")
|
||||
|
||||
def test_get_top_discount_codes_used(self):
|
||||
"""
|
||||
Test to check for the top coupon codes used.
|
||||
"""
|
||||
self.login_user(self.user.username)
|
||||
self.add_coupon(self.course_key, True, 'Ad123asd')
|
||||
self.add_coupon(self.course_key, True, '32213asd')
|
||||
self.purchases_using_coupon_codes()
|
||||
top_discounted_codes = CouponRedemption.get_top_discount_codes_used(self.course_key)
|
||||
self.assertTrue(top_discounted_codes[0]['coupon__code'], 'Ad123asd')
|
||||
self.assertTrue(top_discounted_codes[0]['coupon__used_count'], 1)
|
||||
self.assertTrue(top_discounted_codes[1]['coupon__code'], '32213asd')
|
||||
self.assertTrue(top_discounted_codes[1]['coupon__used_count'], 2)
|
||||
|
||||
def test_get_total_coupon_code_purchases(self):
|
||||
"""
|
||||
Test to assert the number of coupon code purchases.
|
||||
"""
|
||||
self.login_user(self.user.username)
|
||||
self.add_coupon(self.course_key, True, 'Ad123asd')
|
||||
self.add_coupon(self.course_key, True, '32213asd')
|
||||
self.purchases_using_coupon_codes()
|
||||
|
||||
total_coupon_code_purchases = CouponRedemption.get_total_coupon_code_purchases(self.course_key)
|
||||
self.assertTrue(total_coupon_code_purchases['coupon__count'], 3)
|
||||
|
||||
def test_get_self_purchased_seat_count(self):
|
||||
"""
|
||||
Test to assert the number of seats
|
||||
purchased using individual purchases.
|
||||
"""
|
||||
PaidCourseRegistration.add_to_order(self.cart, self.course_key)
|
||||
self.cart.purchase()
|
||||
|
||||
test_student = UserFactory.create()
|
||||
test_student.set_password('password')
|
||||
test_student.save()
|
||||
|
||||
self.cart = Order.get_cart_for_user(test_student)
|
||||
PaidCourseRegistration.add_to_order(self.cart, self.course_key)
|
||||
self.cart.purchase()
|
||||
|
||||
total_seats_count = PaidCourseRegistration.get_self_purchased_seat_count(course_key=self.course_key)
|
||||
self.assertTrue(total_seats_count, 2)
|
||||
|
||||
def purchases_using_coupon_codes(self):
|
||||
"""
|
||||
helper method that uses coupon codes when purchasing courses.
|
||||
"""
|
||||
self.cart.order_type = 'business'
|
||||
self.cart.save()
|
||||
CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': 'Ad123asd'})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.cart.purchase()
|
||||
|
||||
self.cart.clear()
|
||||
self.cart = Order.get_cart_for_user(self.user)
|
||||
self.cart.order_type = 'business'
|
||||
self.cart.save()
|
||||
CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': 'Ad123asd'})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.cart.purchase()
|
||||
|
||||
self.cart.clear()
|
||||
self.cart = Order.get_cart_for_user(self.user)
|
||||
PaidCourseRegistration.add_to_order(self.cart, self.course_key)
|
||||
resp = self.client.post(reverse('shoppingcart.views.use_code'), {'code': '32213asd'})
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.cart.purchase()
|
||||
|
||||
def test_cart_type_business(self):
|
||||
self.cart.order_type = 'business'
|
||||
self.cart.save()
|
||||
item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
|
||||
self.cart.purchase()
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course_key))
|
||||
# check that the registration codes are generated against the order
|
||||
registration_codes = CourseRegistrationCode.order_generated_registration_codes(self.course_key)
|
||||
self.assertEqual(registration_codes.count(), item.qty)
|
||||
|
||||
def test_regcode_redemptions(self):
|
||||
"""
|
||||
Asserts the data model around RegistrationCodeRedemption
|
||||
"""
|
||||
self.cart.order_type = 'business'
|
||||
self.cart.save()
|
||||
CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
|
||||
self.cart.purchase()
|
||||
|
||||
reg_code = CourseRegistrationCode.order_generated_registration_codes(self.course_key)[0]
|
||||
|
||||
enrollment = CourseEnrollment.enroll(self.user, self.course_key)
|
||||
|
||||
redemption = RegistrationCodeRedemption(
|
||||
registration_code=reg_code,
|
||||
redeemed_by=self.user,
|
||||
course_enrollment=enrollment
|
||||
)
|
||||
redemption.save()
|
||||
|
||||
test_redemption = RegistrationCodeRedemption.registration_code_used_for_enrollment(enrollment)
|
||||
|
||||
self.assertEqual(test_redemption.id, redemption.id)
|
||||
|
||||
def test_regcode_multi_redemptions(self):
|
||||
"""
|
||||
Asserts the data model around RegistrationCodeRedemption and
|
||||
what happens when we do multiple redemptions by same user
|
||||
"""
|
||||
self.cart.order_type = 'business'
|
||||
self.cart.save()
|
||||
CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
|
||||
self.cart.purchase()
|
||||
|
||||
reg_codes = CourseRegistrationCode.order_generated_registration_codes(self.course_key)
|
||||
|
||||
self.assertEqual(len(reg_codes), 2)
|
||||
|
||||
enrollment = CourseEnrollment.enroll(self.user, self.course_key)
|
||||
|
||||
ids = []
|
||||
for reg_code in reg_codes:
|
||||
redemption = RegistrationCodeRedemption(
|
||||
registration_code=reg_code,
|
||||
redeemed_by=self.user,
|
||||
course_enrollment=enrollment
|
||||
)
|
||||
redemption.save()
|
||||
ids.append(redemption.id)
|
||||
|
||||
test_redemption = RegistrationCodeRedemption.registration_code_used_for_enrollment(enrollment)
|
||||
|
||||
self.assertIn(test_redemption.id, ids)
|
||||
|
||||
def test_add_with_default_mode(self):
|
||||
"""
|
||||
Tests add_to_cart where the mode specified in the argument is NOT
|
||||
in the database and NOT the default "audit". In this case it
|
||||
just adds the user in the CourseMode.DEFAULT_MODE for free.
|
||||
"""
|
||||
reg1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key, mode_slug="DNE")
|
||||
|
||||
self.assertEqual(reg1.unit_cost, 0)
|
||||
self.assertEqual(reg1.line_cost, 0)
|
||||
self.assertEqual(reg1.mode, CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG)
|
||||
self.assertEqual(reg1.user, self.user)
|
||||
self.assertEqual(reg1.status, "cart")
|
||||
self.assertEqual(self.cart.total_cost, 0)
|
||||
self.assertTrue(PaidCourseRegistration.contained_in_order(self.cart, self.course_key))
|
||||
|
||||
course_reg_code_item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2, mode_slug="DNE")
|
||||
|
||||
self.assertEqual(course_reg_code_item.unit_cost, 0)
|
||||
self.assertEqual(course_reg_code_item.line_cost, 0)
|
||||
self.assertEqual(course_reg_code_item.mode, CourseMode.DEFAULT_SHOPPINGCART_MODE_SLUG)
|
||||
self.assertEqual(course_reg_code_item.user, self.user)
|
||||
self.assertEqual(course_reg_code_item.status, "cart")
|
||||
self.assertEqual(self.cart.total_cost, 0)
|
||||
self.assertTrue(CourseRegCodeItem.contained_in_order(self.cart, self.course_key))
|
||||
|
||||
def test_add_course_reg_item_with_no_course_item(self):
|
||||
fake_course_id = CourseLocator(org="edx", course="fake", run="course")
|
||||
with self.assertRaises(CourseDoesNotExistException):
|
||||
CourseRegCodeItem.add_to_order(self.cart, fake_course_id, 2)
|
||||
|
||||
def test_course_reg_item_already_in_cart(self):
|
||||
CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
|
||||
with self.assertRaises(ItemAlreadyInCartException):
|
||||
CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
|
||||
|
||||
def test_course_reg_item_already_enrolled_in_course(self):
|
||||
CourseEnrollment.enroll(self.user, self.course_key)
|
||||
with self.assertRaises(AlreadyEnrolledInCourseException):
|
||||
CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
|
||||
|
||||
def test_purchased_callback(self):
|
||||
reg1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key)
|
||||
self.cart.purchase()
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course_key))
|
||||
reg1 = PaidCourseRegistration.objects.get(id=reg1.id) # reload from DB to get side-effect
|
||||
self.assertEqual(reg1.status, "purchased")
|
||||
self.assertIsNotNone(reg1.course_enrollment)
|
||||
self.assertEqual(reg1.course_enrollment.id, CourseEnrollment.objects.get(user=self.user, course_id=self.course_key).id)
|
||||
|
||||
def test_generate_receipt_instructions(self):
|
||||
"""
|
||||
Add 2 courses to the order and make sure the instruction_set only contains 1 element (no dups)
|
||||
"""
|
||||
course2 = CourseFactory.create()
|
||||
course_mode2 = CourseMode(course_id=course2.id,
|
||||
mode_slug="honor",
|
||||
mode_display_name="honor cert",
|
||||
min_price=self.cost)
|
||||
course_mode2.save()
|
||||
pr1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key)
|
||||
pr2 = PaidCourseRegistration.add_to_order(self.cart, course2.id)
|
||||
self.cart.purchase()
|
||||
inst_dict, inst_set = self.cart.generate_receipt_instructions()
|
||||
self.assertEqual(2, len(inst_dict))
|
||||
self.assertEqual(1, len(inst_set))
|
||||
self.assertIn("dashboard", inst_set.pop())
|
||||
self.assertIn(pr1.pk_with_subclass, inst_dict)
|
||||
self.assertIn(pr2.pk_with_subclass, inst_dict)
|
||||
|
||||
def test_purchased_callback_exception(self):
|
||||
reg1 = PaidCourseRegistration.add_to_order(self.cart, self.course_key)
|
||||
reg1.course_id = CourseLocator(org="changed", course="forsome", run="reason")
|
||||
reg1.save()
|
||||
with self.assertRaises(PurchasedCallbackException):
|
||||
reg1.purchased_callback()
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course_key))
|
||||
|
||||
reg1.course_id = CourseLocator(org="abc", course="efg", run="hij")
|
||||
reg1.save()
|
||||
with self.assertRaises(PurchasedCallbackException):
|
||||
reg1.purchased_callback()
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course_key))
|
||||
|
||||
course_reg_code_item = CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2)
|
||||
course_reg_code_item.course_id = CourseLocator(org="changed1", course="forsome1", run="reason1")
|
||||
course_reg_code_item.save()
|
||||
with self.assertRaises(PurchasedCallbackException):
|
||||
course_reg_code_item.purchased_callback()
|
||||
|
||||
def test_user_cart_has_both_items(self):
|
||||
"""
|
||||
This test exists b/c having both CertificateItem and PaidCourseRegistration in an order used to break
|
||||
PaidCourseRegistration.contained_in_order
|
||||
"""
|
||||
cart = Order.get_cart_for_user(self.user)
|
||||
CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
|
||||
PaidCourseRegistration.add_to_order(self.cart, self.course_key)
|
||||
self.assertTrue(PaidCourseRegistration.contained_in_order(cart, self.course_key))
|
||||
|
||||
|
||||
class CertificateItemTest(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests for verifying specific CertificateItem functionality
|
||||
|
||||
@@ -1239,94 +1239,6 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
|
||||
self.assertEqual(context['currency_symbol'], 'Rs')
|
||||
self.assertEqual(context['currency'], 'PKR')
|
||||
|
||||
@patch('shoppingcart.views.render_to_response', render_mock)
|
||||
def test_courseregcode_item_total_price(self):
|
||||
self.cart.order_type = 'business'
|
||||
self.cart.save()
|
||||
CourseRegCodeItem.add_to_order(self.cart, self.course_key, 2, mode_slug=self.course_mode.mode_slug)
|
||||
self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
|
||||
self.assertEqual(CourseRegCodeItem.get_total_amount_of_purchased_item(self.course_key), 80)
|
||||
|
||||
@patch('shoppingcart.views.render_to_response', render_mock)
|
||||
def test_show_receipt_success_with_order_type_business(self):
|
||||
self.cart.order_type = 'business'
|
||||
self.cart.save()
|
||||
reg_item = CourseRegCodeItem.add_to_order(
|
||||
self.cart,
|
||||
self.course_key,
|
||||
2,
|
||||
mode_slug=self.course_mode.mode_slug
|
||||
)
|
||||
self.cart.add_billing_details(company_name='T1Omega', company_contact_name='C1',
|
||||
company_contact_email='test@t1.com', recipient_email='test@t2.com')
|
||||
self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
|
||||
|
||||
# mail is sent to these emails recipient_email, company_contact_email, order.user.email
|
||||
self.assertEqual(len(mail.outbox), 3)
|
||||
|
||||
self.login_user()
|
||||
resp = self.client.get(reverse('shoppingcart.views.show_receipt', args=[self.cart.id]))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
# when order_type = 'business' the user is not enrolled in the
|
||||
# course but presented with the enrollment links
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(self.cart.user, self.course_key))
|
||||
self.assertContains(resp, 'FirstNameTesting123')
|
||||
self.assertContains(resp, '80.00')
|
||||
# check for the enrollment codes content
|
||||
self.assertContains(
|
||||
resp,
|
||||
'Please send each professional one of these unique registration codes to enroll into the course.',
|
||||
)
|
||||
|
||||
# fetch the newly generated registration codes
|
||||
course_registration_codes = CourseRegistrationCode.objects.filter(order=self.cart)
|
||||
|
||||
((template, context), _) = render_mock.call_args # pylint: disable=unpacking-non-sequence
|
||||
self.assertEqual(template, 'shoppingcart/receipt.html')
|
||||
self.assertEqual(context['order'], self.cart)
|
||||
self.assertIn(reg_item, context['shoppingcart_items'][0])
|
||||
# now check for all the registration codes in the receipt
|
||||
# and all the codes should be unused at this point
|
||||
self.assertIn(course_registration_codes[0].code, context['reg_code_info_list'][0]['code'])
|
||||
self.assertIn(course_registration_codes[1].code, context['reg_code_info_list'][1]['code'])
|
||||
self.assertFalse(context['reg_code_info_list'][0]['is_redeemed'])
|
||||
self.assertFalse(context['reg_code_info_list'][1]['is_redeemed'])
|
||||
|
||||
self.assertContains(
|
||||
resp,
|
||||
self.cart.purchase_time.strftime(u"%B %d, %Y"),
|
||||
)
|
||||
self.assertContains(resp, self.cart.company_name)
|
||||
self.assertContains(resp, self.cart.company_contact_name)
|
||||
self.assertContains(resp, self.cart.company_contact_email)
|
||||
self.assertContains(resp, self.cart.recipient_email)
|
||||
self.assertIn(u"Invoice #{order_id}".format(order_id=self.cart.id), resp.content.decode(resp.charset))
|
||||
codes_string = u'You have successfully purchased <b>{total_registration_codes} course registration codes'
|
||||
self.assertIn(codes_string.format(
|
||||
total_registration_codes=context['total_registration_codes']),
|
||||
resp.content.decode(resp.charset)
|
||||
)
|
||||
|
||||
# now redeem one of registration code from the previous order
|
||||
redeem_url = reverse('register_code_redemption', args=[context['reg_code_info_list'][0]['code']])
|
||||
|
||||
#now activate the user by enrolling him/her to the course
|
||||
response = self.client.post(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, 'View Dashboard')
|
||||
|
||||
# now view the receipt page again to see if any registration codes
|
||||
# has been expired or not
|
||||
resp = self.client.get(reverse('shoppingcart.views.show_receipt', args=[self.cart.id]))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
((template, context), _) = render_mock.call_args # pylint: disable=unpacking-non-sequence
|
||||
self.assertEqual(template, 'shoppingcart/receipt.html')
|
||||
# now check for all the registration codes in the receipt
|
||||
# and one of code should be used at this point
|
||||
self.assertTrue(context['reg_code_info_list'][0]['is_redeemed'])
|
||||
self.assertFalse(context['reg_code_info_list'][1]['is_redeemed'])
|
||||
|
||||
@patch('shoppingcart.views.render_to_response', render_mock)
|
||||
def test_show_receipt_success_with_upgrade(self):
|
||||
|
||||
@@ -1780,108 +1692,6 @@ class RegistrationCodeRedemptionCourseEnrollment(SharedModuleStoreTestCase):
|
||||
|
||||
cache.clear()
|
||||
|
||||
def test_course_enrollment_active_registration_code_redemption(self):
|
||||
"""
|
||||
Test for active registration code course enrollment
|
||||
"""
|
||||
cache.clear()
|
||||
instructor = InstructorFactory(course_key=self.course_key)
|
||||
self.client.login(username=instructor.username, password='test')
|
||||
|
||||
# Registration Code Generation only available to Sales Admins.
|
||||
CourseSalesAdminRole(self.course.id).add_users(instructor)
|
||||
|
||||
url = reverse('generate_registration_codes',
|
||||
kwargs={'course_id': text_type(self.course.id)})
|
||||
|
||||
data = {
|
||||
'total_registration_codes': 12, 'company_name': 'Test Group', 'company_contact_name': 'Test@company.com',
|
||||
'company_contact_email': 'Test@company.com', 'unit_price': 122.45, 'recipient_name': 'Test123',
|
||||
'recipient_email': 'test@123.com', 'address_line_1': 'Portland Street',
|
||||
'address_line_2': '', 'address_line_3': '', 'city': '', 'state': '', 'zip': '', 'country': '',
|
||||
'customer_reference_number': '123A23F', 'internal_reference': '', 'invoice': ''
|
||||
}
|
||||
|
||||
response = self.client.post(url, data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# get the first registration from the newly created registration codes
|
||||
registration_code = CourseRegistrationCode.objects.all()[0].code
|
||||
redeem_url = reverse('register_code_redemption', args=[registration_code])
|
||||
self.login_user()
|
||||
|
||||
response = self.client.get(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# check button text
|
||||
self.assertContains(response, 'Activate Course Enrollment')
|
||||
|
||||
#now activate the user by enrolling him/her to the course
|
||||
response = self.client.post(redeem_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, 'View Dashboard')
|
||||
|
||||
#now check that the registration code has already been redeemed and user is already registered in the course
|
||||
RegistrationCodeRedemption.objects.filter(registration_code__code=registration_code)
|
||||
response = self.client.get(redeem_url)
|
||||
self.assertEqual(len(RegistrationCodeRedemption.objects.filter(registration_code__code=registration_code)), 1)
|
||||
self.assertContains(response, "You've clicked a link for an enrollment code that has already been used.")
|
||||
|
||||
#now check that the registration code has already been redeemed
|
||||
response = self.client.post(redeem_url)
|
||||
self.assertContains(response, "You've clicked a link for an enrollment code that has already been used.")
|
||||
|
||||
#now check the response of the dashboard page
|
||||
dashboard_url = reverse('dashboard')
|
||||
response = self.client.get(dashboard_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, self.course.display_name.encode('utf-8'))
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class RedeemCodeEmbargoTests(UrlResetMixin, ModuleStoreTestCase):
|
||||
"""Test blocking redeem code redemption based on country access rules. """
|
||||
|
||||
USERNAME = 'bob'
|
||||
PASSWORD = 'test'
|
||||
|
||||
URLCONF_MODULES = ['openedx.core.djangoapps.embargo']
|
||||
|
||||
@patch.dict(settings.FEATURES, {'EMBARGO': True})
|
||||
def setUp(self):
|
||||
super(RedeemCodeEmbargoTests, self).setUp()
|
||||
self.course = CourseFactory.create()
|
||||
self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD)
|
||||
result = self.client.login(username=self.user.username, password=self.PASSWORD)
|
||||
self.assertTrue(result, msg="Could not log in")
|
||||
|
||||
@ddt.data('get', 'post')
|
||||
@patch.dict(settings.FEATURES, {'EMBARGO': True})
|
||||
def test_registration_code_redemption_embargo(self, method):
|
||||
# Create a valid registration code
|
||||
reg_code = CourseRegistrationCode.objects.create(
|
||||
code="abcd1234",
|
||||
course_id=self.course.id,
|
||||
created_by=self.user
|
||||
)
|
||||
|
||||
# Try to redeem the code from a restricted country
|
||||
with restrict_course(self.course.id) as redirect_url:
|
||||
url = reverse(
|
||||
'register_code_redemption',
|
||||
kwargs={'registration_code': 'abcd1234'}
|
||||
)
|
||||
response = getattr(self.client, method)(url)
|
||||
self.assertRedirects(response, redirect_url)
|
||||
|
||||
# The registration code should NOT be redeemed
|
||||
is_redeemed = RegistrationCodeRedemption.objects.filter(
|
||||
registration_code=reg_code
|
||||
).exists()
|
||||
self.assertFalse(is_redeemed)
|
||||
|
||||
# The user should NOT be enrolled
|
||||
is_enrolled = CourseEnrollment.is_enrolled(self.user, self.course.id)
|
||||
self.assertFalse(is_enrolled)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class DonationViewTest(SharedModuleStoreTestCase):
|
||||
|
||||
@@ -37,7 +37,6 @@ from lms.djangoapps.verify_student.views import PayAndVerifyView, checkout_with_
|
||||
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
|
||||
from shoppingcart.models import CertificateItem, Order
|
||||
from student.models import CourseEnrollment
|
||||
from student.tests.factories import CourseEnrollmentFactory, UserFactory
|
||||
from util.testing import UrlResetMixin
|
||||
@@ -1225,21 +1224,6 @@ class CheckoutTestMixin(object):
|
||||
self.assertEqual(data, {'foo': 'bar'})
|
||||
|
||||
|
||||
@patch('lms.djangoapps.verify_student.views.checkout_with_shoppingcart', return_value=TEST_PAYMENT_DATA, autospec=True)
|
||||
class TestCreateOrderShoppingCart(CheckoutTestMixin, ModuleStoreTestCase):
|
||||
""" Test view behavior when the shoppingcart is used. """
|
||||
|
||||
def make_sku(self):
|
||||
""" Checkout is handled by shoppingcart when the course mode's sku is empty. """
|
||||
return ''
|
||||
|
||||
def _get_checkout_args(self, patched_create_order):
|
||||
""" Assuming patched_create_order was called, return a mapping containing the call arguments."""
|
||||
return dict(
|
||||
list(zip(('request', 'user', 'course_key', 'course_mode', 'amount'), patched_create_order.call_args[0]))
|
||||
)
|
||||
|
||||
|
||||
@override_settings(ECOMMERCE_API_URL=TEST_API_URL)
|
||||
@patch(
|
||||
'lms.djangoapps.verify_student.views.checkout_with_ecommerce_service',
|
||||
@@ -1304,113 +1288,6 @@ class TestCheckoutWithEcommerceService(ModuleStoreTestCase):
|
||||
self.assertEqual(actual_payment_data, expected_payment_data)
|
||||
|
||||
|
||||
class TestCreateOrderView(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests for the create_order view of verified course enrollment process.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestCreateOrderView, self).setUp()
|
||||
|
||||
self.user = UserFactory.create(username="rusty", password="test")
|
||||
self.client.login(username="rusty", password="test")
|
||||
self.course_id = 'Robot/999/Test_Course'
|
||||
self.course = CourseFactory.create(org='Robot', number='999', display_name='Test Course')
|
||||
verified_mode = CourseMode(
|
||||
course_id=CourseKey.from_string("Robot/999/Test_Course"),
|
||||
mode_slug="verified",
|
||||
mode_display_name="Verified Certificate",
|
||||
min_price=50
|
||||
)
|
||||
verified_mode.save()
|
||||
course_mode_post_data = {
|
||||
'certificate_mode': 'Select Certificate',
|
||||
'contribution': 50,
|
||||
'contribution-other-amt': '',
|
||||
'explain': ''
|
||||
}
|
||||
self.client.post(
|
||||
reverse("course_modes_choose", kwargs={'course_id': self.course_id}),
|
||||
course_mode_post_data
|
||||
)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True})
|
||||
def test_invalid_amount(self):
|
||||
response = self._create_order('1.a', self.course_id, expect_status_code=400)
|
||||
self.assertContains(response, 'Selected price is not valid number.', status_code=400)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True})
|
||||
def test_invalid_mode(self):
|
||||
# Create a course that does not have a verified mode
|
||||
course_id = 'Fake/999/Test_Course'
|
||||
CourseFactory.create(org='Fake', number='999', display_name='Test Course')
|
||||
response = self._create_order('50', course_id, expect_status_code=400)
|
||||
self.assertContains(
|
||||
response,
|
||||
'This course doesn\'t support paid certificates',
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True})
|
||||
def test_create_order_fail_with_get(self):
|
||||
create_order_post_data = {
|
||||
'contribution': 50,
|
||||
'course_id': self.course_id,
|
||||
}
|
||||
|
||||
# Use the wrong HTTP method
|
||||
response = self.client.get(reverse('verify_student_create_order'), create_order_post_data)
|
||||
self.assertEqual(response.status_code, 405)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True})
|
||||
def test_create_order_success(self):
|
||||
response = self._create_order(50, self.course_id)
|
||||
json_response = json.loads(response.content.decode('utf-8'))
|
||||
self.assertIsNotNone(json_response['payment_form_data'].get('orderNumber')) # TODO not canonical
|
||||
|
||||
# Verify that the order exists and is configured correctly
|
||||
order = Order.objects.get(user=self.user)
|
||||
self.assertEqual(order.status, 'paying')
|
||||
item = CertificateItem.objects.get(order=order)
|
||||
self.assertEqual(item.status, 'paying')
|
||||
self.assertEqual(item.course_id, self.course.id)
|
||||
self.assertEqual(item.mode, 'verified')
|
||||
|
||||
def _create_order(self, contribution, course_id, expect_success=True, expect_status_code=200):
|
||||
"""Create a new order.
|
||||
|
||||
Arguments:
|
||||
contribution (int): The contribution amount.
|
||||
course_id (CourseKey): The course to purchase.
|
||||
|
||||
Keyword Arguments:
|
||||
expect_success (bool): If True, verify that the response was successful.
|
||||
expect_status_code (int): The expected HTTP status code
|
||||
|
||||
Returns:
|
||||
HttpResponse
|
||||
|
||||
"""
|
||||
url = reverse('verify_student_create_order')
|
||||
data = {
|
||||
'contribution': contribution,
|
||||
'course_id': course_id,
|
||||
'processor': '',
|
||||
}
|
||||
|
||||
response = self.client.post(url, data)
|
||||
self.assertEqual(response.status_code, expect_status_code)
|
||||
|
||||
if expect_status_code == 200:
|
||||
json_response = json.loads(response.content.decode('utf-8'))
|
||||
if expect_success:
|
||||
self.assertEqual(set(json_response.keys()), PAYMENT_DATA_KEYS)
|
||||
else:
|
||||
self.assertFalse(json_response['success'])
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True})
|
||||
class TestSubmitPhotosForVerification(MockS3BotoMixin, TestVerificationBase):
|
||||
|
||||
Reference in New Issue
Block a user