diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py index ff7570cc9e..86585492e2 100644 --- a/lms/djangoapps/instructor/tests/test_api.py +++ b/lms/djangoapps/instructor/tests/test_api.py @@ -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): diff --git a/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py b/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py index 7bd2d561b1..3a140a057b 100644 --- a/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py +++ b/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py @@ -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, '') - @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), diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py index 14a3a28929..31ad3def55 100644 --- a/lms/djangoapps/instructor/views/api.py +++ b/lms/djangoapps/instructor/views/api.py @@ -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 ( diff --git a/lms/djangoapps/instructor_analytics/tests/test_basic.py b/lms/djangoapps/instructor_analytics/tests/test_basic.py index ef1d8d2b86..779344c12b 100644 --- a/lms/djangoapps/instructor_analytics/tests/test_basic.py +++ b/lms/djangoapps/instructor_analytics/tests/test_basic.py @@ -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] - ) diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index 7c131e6f90..54ca4a154e 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -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', '2' - ] - 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. diff --git a/lms/djangoapps/shoppingcart/tests/test_models.py b/lms/djangoapps/shoppingcart/tests/test_models.py index 48ed275dde..09c00c1a3f 100644 --- a/lms/djangoapps/shoppingcart/tests/test_models.py +++ b/lms/djangoapps/shoppingcart/tests/test_models.py @@ -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 diff --git a/lms/djangoapps/shoppingcart/tests/test_views.py b/lms/djangoapps/shoppingcart/tests/test_views.py index d29c377573..79405d50a8 100644 --- a/lms/djangoapps/shoppingcart/tests/test_views.py +++ b/lms/djangoapps/shoppingcart/tests/test_views.py @@ -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 {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): diff --git a/lms/djangoapps/verify_student/tests/test_views.py b/lms/djangoapps/verify_student/tests/test_views.py index bd5555e253..0ce69fff89 100644 --- a/lms/djangoapps/verify_student/tests/test_views.py +++ b/lms/djangoapps/verify_student/tests/test_views.py @@ -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):