def test_update_exam_authorization_order(self, order_status): """ Verify that update_exam_authorization_final_grade is called when a fulfilled Order saves """ with mute_signals(post_save): # muted because enrollment also trigger signal for profile creation. right now we are just # looking final grades CachedEnrollmentFactory.create(user=self.profile.user, course_run=self.course_run) FinalGradeFactory.create( user=self.profile.user, course_run=self.course_run, passed=True, ) order = OrderFactory.create(user=self.profile.user, fulfilled=False) LineFactory.create(course_key=self.course_run.edx_course_key, order=order) # There is no ExamProfile or ExamAuthorization before creating the FinalGrade. assert ExamProfile.objects.filter(profile=self.profile).exists() is False assert ExamAuthorization.objects.filter( user=self.profile.user, course=self.course_run.course ).exists() is False order.status = order_status order.save() # assert Exam Authorization and profile created. assert ExamProfile.objects.filter(profile=self.profile).exists() is True assert ExamAuthorization.objects.filter( user=self.profile.user, course=self.course_run.course ).exists() is True
def create(cls, **kwargs): """ Overrides the default .create() method. Creates an Order/Line for an FA course if the client asked for a 'verified' enrollment specifically """ created_obj = super().create(**kwargs) if kwargs.get('verified') is True: course_run = created_obj.course_run program = course_run.course.program if program.financial_aid_availability: LineFactory.create(course_key=course_run.edx_course_key, order__status=Order.FULFILLED) return created_obj
def create(cls, **kwargs): """ Overrides the default .create() method. Creates an Order/Line for an FA course if the client asked for a 'verified' enrollment specifically """ created_obj = super().create(**kwargs) if kwargs.get('verified') is True: course_run = created_obj.course_run program = course_run.course.program if program.financial_aid_availability: LineFactory.create(course_key=course_run.edx_course_key, order__status=Order.FULFILLED) return created_obj
def test_serialize_order(status): """Test that OrderToDealSerializer produces the correct serialized data""" order = OrderFactory.create(status=status) line = LineFactory.create(order=order) serialized_data = OrderToDealSerializer(instance=order).data assert serialized_data == { "id": order.id, "name": f"XPRO-ORDER-{order.id}", "purchaser": format_hubspot_id(order.purchaser.id), "stage": ORDER_STATUS_MAPPING[status], "amount": line.product_version.price.to_eng_string(), "discount_amount": "0.0000", "close_date": ( int(order.updated_on.timestamp() * 1000) if status == Order.FULFILLED else None ), "coupon_code": None, "company": None, "payment_type": None, "payment_transaction": None, "discount_percent": "0", "order_type": ORDER_TYPE_B2C, "lines": [LineSerializer(instance=line).data], "status": order.status, }
def test_serialize_order_with_coupon(): """Test that OrderToDealSerializer produces the correct serialized data for an order with coupon""" line = LineFactory.create() order = line.order coupon_redemption = CouponRedemptionFactory.create(order=order) discount = round_half_up( coupon_redemption.coupon_version.payment_version.amount * line.product_version.price ) serialized_data = OrderToDealSerializer(instance=order).data assert serialized_data == { "id": order.id, "name": f"XPRO-ORDER-{order.id}", "purchaser": format_hubspot_id(order.purchaser.id), "stage": ORDER_STATUS_MAPPING[order.status], "amount": line.product_version.price.to_eng_string(), "discount_amount": discount.to_eng_string(), "close_date": ( int(order.updated_on.timestamp() * 1000) if order.status == Order.FULFILLED else None ), "coupon_code": coupon_redemption.coupon_version.coupon.coupon_code, "company": coupon_redemption.coupon_version.payment_version.company.name, "order_type": ORDER_TYPE_B2B, "payment_type": coupon_redemption.coupon_version.payment_version.payment_type, "payment_transaction": coupon_redemption.coupon_version.payment_version.payment_transaction, "discount_percent": ( coupon_redemption.coupon_version.payment_version.amount * 100 ).to_eng_string(), "lines": [LineSerializer(instance=line).data], "status": order.status, }
def setUpTestData(cls): super().setUpTestData() cls.user = UserFactory() cls.user.social_auth.create( provider='not_edx', ) cls.user.social_auth.create( provider=EdxOrgOAuth2.name, uid="{}_edx".format(cls.user.username), ) cls.order = OrderFactory.create(status=Order.CREATED, user=cls.user) cls.line1 = LineFactory.create(order=cls.order) cls.line2 = LineFactory.create(order=cls.order) cls.course_run1 = CourseRunFactory.create(edx_course_key=cls.line1.course_key) cls.course_run2 = CourseRunFactory.create(edx_course_key=cls.line2.course_key)
def setUpTestData(cls): super().setUpTestData() cls.user = UserFactory() cls.user.social_auth.create( provider='not_edx', ) cls.user.social_auth.create( provider=EdxOrgOAuth2.name, uid="{}_edx".format(cls.user.username), ) cls.order = OrderFactory.create(status=Order.CREATED, user=cls.user) cls.line1 = LineFactory.create(order=cls.order) cls.line2 = LineFactory.create(order=cls.order) cls.course_run1 = CourseRunFactory.create(edx_course_key=cls.line1.course_key) cls.course_run2 = CourseRunFactory.create(edx_course_key=cls.line2.course_key)
def test_line_str(self): """Test Line.__str__""" line = LineFactory.create() assert str(line) == "Line for order {}, course_key={}, price={}".format( line.order.id, line.course_key, line.price, )
def create_order(user, course_run): """" create payment for course """ return LineFactory.create( course_key=course_run.edx_course_key, order__fulfilled=True, order__user=user, ).order
def create_order(user, course_run): """" create payment for course """ return LineFactory.create( course_key=course_run.edx_course_key, order__fulfilled=True, order__user=user, ).order
def test_another_user_already_redeemed(self, order_status, other_user_redeemed, is_automatic, expected): """ Tests for Coupon.another_user_already_redeemed """ run1 = CourseRunFactory.create(course__program__financial_aid_availability=True) run2 = CourseRunFactory.create(course=run1.course) coupon = CouponFactory.create( content_object=run1.course, coupon_type=Coupon.DISCOUNTED_PREVIOUS_COURSE if is_automatic else Coupon.STANDARD, ) line1 = LineFactory.create(course_key=run1.edx_course_key, order__status=Order.FULFILLED) RedeemedCoupon.objects.create(order=line1.order, coupon=coupon) if other_user_redeemed: line2 = LineFactory.create(course_key=run2.edx_course_key, order__status=order_status) RedeemedCoupon.objects.create(order=line2.order, coupon=coupon) assert coupon.another_user_already_redeemed(line1.order.user) is expected
def test_sync_line_item_with_hubspot(mock_hubspot_request): """Test that send_hubspot_request is called properly for a LINE_ITEM sync""" line = LineFactory.create() sync_line_item_with_hubspot(line.id) body = make_line_item_sync_message(line.id) body[0]["changeOccurredTimestamp"] = ANY mock_hubspot_request.assert_called_once_with("LINE_ITEM", HUBSPOT_SYNC_URL, "PUT", body=body)
def test_to_dict(self): """ Test Order.to_dict() """ order = OrderFactory.create() lines = [LineFactory.create(order=order) for _ in range(5)] data = order.to_dict() lines_data = data.pop('lines') assert serialize_model_object(order) == data assert lines_data == [serialize_model_object(line) for line in lines]
def pay_for_fa_course(self, course_id, status=Order.FULFILLED): """ Helper function to pay for a financial aid course """ order = OrderFactory.create( user=self.user, status=status ) return LineFactory.create( order=order, course_key=course_id )
def pay_for_fa_course(self, course_id, status=Order.FULFILLED): """ Helper function to pay for a financial aid course """ order = OrderFactory.create( user=self.user, status=status ) return LineFactory.create( order=order, course_key=course_id )
def test_zero_price_checkout_failed_enroll(self): """ If we do a $0 checkout but the enrollment fails, we should send an email but leave the order as fulfilled """ user = UserFactory.create() self.client.force_login(user) course_run = CourseRunFactory.create( course__program__live=True, course__program__financial_aid_availability=True, ) order = LineFactory.create( order__status=Order.CREATED, order__total_price_paid=0, price=0, ).order with patch( 'ecommerce.views.create_unfulfilled_order', autospec=True, return_value=order, ) as create_mock, patch( 'ecommerce.views.enroll_user_on_success', side_effect=KeyError, ) as enroll_user_mock, patch( 'ecommerce.views.MailgunClient.send_individual_email', ) as send_email: resp = self.client.post(reverse('checkout'), {'course_id': course_run.edx_course_key}, format='json') assert resp.status_code == status.HTTP_200_OK assert resp.json() == { 'payload': {}, 'url': 'http://testserver/dashboard/?status=receipt&course_key={}'.format( quote_plus(course_run.edx_course_key)), 'method': 'GET', } assert create_mock.call_count == 1 assert create_mock.call_args[0] == (course_run.edx_course_key, user) assert enroll_user_mock.call_count == 1 assert enroll_user_mock.call_args[0] == (order, ) assert send_email.call_count == 1 assert send_email.call_args[0][ 0] == 'Error occurred when enrolling user during $0 checkout' assert send_email.call_args[0][1].startswith( 'Error occurred when enrolling user during $0 checkout for {order}. ' 'Exception: '.format(order=order, )) assert send_email.call_args[0][2] == '*****@*****.**'
def test_serialize_line(): """Test that LineSerializer produces the correct serialized data""" line = LineFactory.create() serialized_data = LineSerializer(instance=line).data assert serialized_data == { "id": line.id, "product": format_hubspot_id(line.product_version.product.id), "order": format_hubspot_id(line.order_id), "quantity": line.quantity, "status": line.order.status, "product_id": line.product_version.text_id, }
def test_zero_price_checkout_failed_enroll(self): """ If we do a $0 checkout but the enrollment fails, we should send an email but leave the order as fulfilled """ user = UserFactory.create() self.client.force_login(user) course_run = CourseRunFactory.create( course__program__live=True, course__program__financial_aid_availability=True, ) order = LineFactory.create( order__status=Order.CREATED, order__total_price_paid=0, price=0, ).order with patch( 'ecommerce.views.create_unfulfilled_order', autospec=True, return_value=order, ) as create_mock, patch( 'ecommerce.views.enroll_user_on_success', side_effect=KeyError, ) as enroll_user_mock, patch( 'ecommerce.views.MailgunClient.send_individual_email', ) as send_email: resp = self.client.post(reverse('checkout'), {'course_id': course_run.edx_course_key}, format='json') assert resp.status_code == status.HTTP_200_OK assert resp.json() == { 'payload': {}, 'url': 'http://testserver/dashboard/?status=receipt&course_key={}'.format( quote_plus(course_run.edx_course_key) ), 'method': 'GET', } assert create_mock.call_count == 1 assert create_mock.call_args[0] == (course_run.edx_course_key, user) assert enroll_user_mock.call_count == 1 assert enroll_user_mock.call_args[0] == (order,) assert send_email.call_count == 1 assert send_email.call_args[0][0] == 'Error occurred when enrolling user during $0 checkout' assert send_email.call_args[0][1].startswith( 'Error occurred when enrolling user during $0 checkout for {order}. ' 'Exception: '.format( order=order, ) ) assert send_email.call_args[0][2] == '*****@*****.**'
def test_update_exam_authorization_order(self, order_status): """ Verify that update_exam_authorization_final_grade is called when a fulfilled Order saves """ with mute_signals(post_save): # muted because enrollment also trigger signal for profile creation. right now we are just # looking final grades CachedEnrollmentFactory.create(user=self.profile.user, course_run=self.course_run) FinalGradeFactory.create( user=self.profile.user, course_run=self.course_run, passed=True, ) order = OrderFactory.create(user=self.profile.user, fulfilled=False) LineFactory.create(course_key=self.course_run.edx_course_key, order=order) # There is no ExamProfile or ExamAuthorization before creating the FinalGrade. assert ExamProfile.objects.filter( profile=self.profile).exists() is False assert ExamAuthorization.objects.filter( user=self.profile.user, course=self.course_run.course).exists() is False order.status = order_status order.save() # assert Exam Authorization and profile created. assert ExamProfile.objects.filter( profile=self.profile).exists() is True assert ExamAuthorization.objects.filter( user=self.profile.user, course=self.course_run.course).exists() is True
def test_user_has_redemptions_left(self, order_status, has_unpurchased_run, another_already_redeemed, expected): """ Coupon.user_has_redemptions_left should be true if user has not yet purchased all course runs """ run1 = CourseRunFactory.create(course__program__financial_aid_availability=True) if has_unpurchased_run: CourseRunFactory.create(course__program=run1.course.program) line = LineFactory.create(course_key=run1.edx_course_key, order__status=order_status) coupon = CouponFactory.create(content_object=run1.course.program) with patch( 'ecommerce.models.Coupon.another_user_already_redeemed', autospec=True, ) as _already_redeemed: _already_redeemed.return_value = another_already_redeemed assert coupon.user_has_redemptions_left(line.order.user) is expected _already_redeemed.assert_called_with(coupon, line.order.user)
def test_creates_order(self): """ An order is created using create_unfulfilled_order and a payload is generated using generate_cybersource_sa_payload """ user = UserFactory.create() self.client.force_login(user) course_run = CourseRunFactory.create( course__program__live=True, course__program__financial_aid_availability=True, ) order = LineFactory.create(order__status=Order.CREATED).order fake_ip = "195.0.0.1" payload = { 'a': 'payload', } with patch( 'ecommerce.views.create_unfulfilled_order', autospec=True, return_value=order, ) as create_mock, patch( 'ecommerce.views.generate_cybersource_sa_payload', autospec=True, return_value=payload, ) as generate_mock, patch("ecommerce.views.get_client_ip", return_value=(fake_ip, True)) as mock_ip_call: resp = self.client.post(reverse('checkout'), {'course_id': course_run.edx_course_key}, format='json') assert mock_ip_call.call_count == 1 assert resp.status_code == status.HTTP_200_OK assert resp.json() == { 'payload': payload, 'url': CYBERSOURCE_SECURE_ACCEPTANCE_URL, 'method': 'POST', } assert create_mock.call_count == 1 assert create_mock.call_args[0] == (course_run.edx_course_key, user) assert generate_mock.call_count == 1 assert generate_mock.call_args[0] == (order, 'http://testserver/dashboard/', fake_ip)
def test_zero_price_checkout(self): """ If the order total is $0, we should just fulfill the order and direct the user to our order receipt page """ user = UserFactory.create() self.client.force_login(user) course_run = CourseRunFactory.create( course__program__live=True, course__program__financial_aid_availability=True, ) order = LineFactory.create( order__status=Order.CREATED, order__total_price_paid=0, price=0, ).order with patch( 'ecommerce.views.create_unfulfilled_order', autospec=True, return_value=order, ) as create_mock, patch('ecommerce.views.enroll_user_on_success', autospec=True) as enroll_user_mock: resp = self.client.post(reverse('checkout'), {'course_id': course_run.edx_course_key}, format='json') assert resp.status_code == status.HTTP_200_OK assert resp.json() == { 'payload': {}, 'url': 'http://testserver/dashboard/?status=receipt&course_key={}'.format( quote_plus(course_run.edx_course_key)), 'method': 'GET', } assert create_mock.call_count == 1 assert create_mock.call_args[0] == (course_run.edx_course_key, user) assert enroll_user_mock.call_count == 1 assert enroll_user_mock.call_args[0] == (order, )
def test_creates_order(self): """ An order is created using create_unfulfilled_order and a payload is generated using generate_cybersource_sa_payload """ user = UserFactory.create() self.client.force_login(user) course_run = CourseRunFactory.create( course__program__live=True, course__program__financial_aid_availability=True, ) order = LineFactory.create(order__status=Order.CREATED).order payload = { 'a': 'payload' } with patch( 'ecommerce.views.create_unfulfilled_order', autospec=True, return_value=order, ) as create_mock, patch( 'ecommerce.views.generate_cybersource_sa_payload', autospec=True, return_value=payload, ) as generate_mock: resp = self.client.post(reverse('checkout'), {'course_id': course_run.edx_course_key}, format='json') assert resp.status_code == status.HTTP_200_OK assert resp.json() == { 'payload': payload, 'url': CYBERSOURCE_SECURE_ACCEPTANCE_URL, 'method': 'POST', } assert create_mock.call_count == 1 assert create_mock.call_args[0] == (course_run.edx_course_key, user) assert generate_mock.call_count == 1 assert generate_mock.call_args[0] == (order, 'http://testserver/dashboard/')
def test_zero_price_checkout(self): """ If the order total is $0, we should just fulfill the order and direct the user to our order receipt page """ user = UserFactory.create() self.client.force_login(user) course_run = CourseRunFactory.create( course__program__live=True, course__program__financial_aid_availability=True, ) order = LineFactory.create( order__status=Order.CREATED, order__total_price_paid=0, price=0, ).order with patch( 'ecommerce.views.create_unfulfilled_order', autospec=True, return_value=order, ) as create_mock, patch('ecommerce.views.enroll_user_on_success', autospec=True) as enroll_user_mock: resp = self.client.post(reverse('checkout'), {'course_id': course_run.edx_course_key}, format='json') assert resp.status_code == status.HTTP_200_OK assert resp.json() == { 'payload': {}, 'url': 'http://testserver/dashboard/?status=receipt&course_key={}'.format( quote_plus(course_run.edx_course_key) ), 'method': 'GET', } assert create_mock.call_count == 1 assert create_mock.call_args[0] == (course_run.edx_course_key, user) assert enroll_user_mock.call_count == 1 assert enroll_user_mock.call_args[0] == (order,)
def test_send_enrollment_failure_message(mocker, is_program): """Test that send_enrollment_failure_message sends a message with proper formatting""" patched_django_mail = mocker.patch("ecommerce.mail_api.mail") product_object = (ProgramFactory.create() if is_program else CourseRunFactory.create()) product_version = ProductVersionFactory.create( product=ProductFactory.create(content_object=product_object)) order = LineFactory.create(product_version=product_version).order details = "TestException on line 21" expected_message = "{name}({email}): Order #{order_id}, {error_obj} #{obj_id} ({obj_title})\n\n{details}".format( name=order.purchaser.username, email=order.purchaser.email, order_id=order.id, error_obj=("Program" if is_program else "Run"), obj_id=product_object.id, obj_title=product_object.title, details=details, ) send_enrollment_failure_message(order, product_object, details) patched_django_mail.send_mail.assert_called_once() send_mail_args = patched_django_mail.send_mail.call_args[0] assert send_mail_args[0] == ENROLL_ERROR_EMAIL_SUBJECT assert send_mail_args[1] == expected_message
def test_send_ecommerce_order_receipt(mocker, receipt_data): """send_ecommerce_order_receipt should send a receipt email""" patched_mail_api = mocker.patch("ecommerce.mail_api.api") date = datetime.datetime(2010, 1, 1, 0, tzinfo=UTC) user = UserFactory.create( name="test", email="*****@*****.**", legal_address__first_name="Test", legal_address__last_name="User", legal_address__street_address_1="11 Main Street", legal_address__country="US", legal_address__state_or_territory="US-CO", legal_address__city="Boulder", legal_address__postal_code="80309", ) line = LineFactory.create( order__status=Order.CREATED, order__id=1, order__created_on=date, order__total_price_paid=0, order__purchaser=user, product_version__price=100, quantity=1, product_version__product__content_object=CourseRunFactory.create( title="test_run_title"), product_version__product__content_object__course__readable_id= "course:/v7/choose-agency", ) # pylint: disable=expression-not-assigned (ReceiptFactory.create(order=line.order, data=receipt_data) if receipt_data else None) send_ecommerce_order_receipt(line.order) patched_mail_api.context_for_user.assert_called_once_with( user=None, extra_context={ "coupon": None, "content_title": "test_run_title", "lines": [{ "quantity": 1, "total_paid": "100.00", "discount": "0.0", "price": "100.00", "readable_id": get_readable_id(line.product_version.product.content_object), "start_date": None, "end_date": None, "content_title": "test_run_title", "CEUs": line.product_version.product.content_object.course.page. certificate_page.CEUs, }], "order_total": "100.00", "order": { "id": 1, "created_on": line.order.created_on, "reference_number": "xpro-b2c-dev-1", }, "receipt": { "card_number": "1234", "card_type": "Visa", "name": "MIT Doof", "payment_method": "card", "bill_to_email": "*****@*****.**", }, "purchaser": { "name": " ".join(["Test", "User"]), "email": "*****@*****.**", "street_address": ["11 Main Street"], "state_code": "CO", "postal_code": "80309", "city": "Boulder", "country": "United States", "company": user.profile.company, }, }, ) patched_mail_api.messages_for_recipients.assert_called_once_with( [("*****@*****.**", patched_mail_api.context_for_user.return_value)], EMAIL_PRODUCT_ORDER_RECEIPT, )
def create_exams(self, current, edx_passed, exam_passed, new_offering, can_schedule, future_exam, need_to_pay): """Create an exam and mark it and the related course as passed or not passed""" # pylint: disable-msg=too-many-arguments self.make_fa_program_enrollment(FinancialAidStatus.AUTO_APPROVED) course = Course.objects.get(title='Digital Learning 200') if current: course_run = CourseRunFactory(course=course) call_command( "alter_data", 'set_to_enrolled', '--username', 'staff', '--course-run-key', course_run.edx_course_key ) FinalGradeFactory.create( user=self.user, course_run=course_run, grade=0.8 if edx_passed else 0.2, passed=True ) else: if edx_passed: call_command( "alter_data", 'set_to_passed', '--username', 'staff', '--course-title', 'Digital Learning 200', '--grade', '75', ) else: call_command( "alter_data", 'set_to_failed', '--username', 'staff', '--course-title', 'Digital Learning 200', '--grade', '45', ) course_run = course.courserun_set.first() ExamProfileFactory.create(status='success', profile=self.user.profile) exam_run = ExamRunFactory.create(course=course, eligibility_past=True, scheduling_past=True) ExamAuthorizationFactory.create( user=self.user, course=course, exam_run=exam_run, status='success', exam_taken=True ) LineFactory.create( order__status=Order.FULFILLED, course_key=course_run ) ProctoredExamGradeFactory.create( user=self.user, course=course, exam_run=exam_run, passed=exam_passed, percentage_grade=0.8 if exam_passed else 0.3 ) if new_offering: CourseRunFactory.create(course=course) if can_schedule: exam_run = ExamRunFactory.create( scheduling_past=False, scheduling_future=False, authorized=True, course=course ) ExamAuthorizationFactory.create( user=self.user, course=course, exam_run=exam_run, status='success', ) if future_exam: ExamRunFactory.create( scheduling_past=False, scheduling_future=True, authorized=True, course=course ) if need_to_pay: exam_run = ExamRunFactory.create(course=course, eligibility_past=True, scheduling_past=True) ExamAuthorizationFactory.create( user=self.user, course=course, exam_run=exam_run, status='success', exam_taken=True ) ProctoredExamGradeFactory.create( user=self.user, course=course, exam_run=exam_run, passed=False, percentage_grade=0.3 )
def test_serialize_order_receipt(receipt_data): """ Test that the OrderReceiptSerializer has correct data """ line = LineFactory.create(order__status=Order.FULFILLED) product_version = line.product_version order = line.order purchaser = order.purchaser.legal_address receipt = ( ReceiptFactory.create(order=order, data=receipt_data) if receipt_data else None ) serialized_data = OrderReceiptSerializer(instance=order).data assert serialized_data == { "coupon": None, "lines": [ { "readable_id": get_readable_id(product_version.product.content_object), "content_title": product_version.product.content_object.title, "discount": "0.0", "start_date": None, "end_date": None, "price": str(product_version.price), "total_paid": str(line.quantity * product_version.price), "quantity": line.quantity, "CEUs": product_version.product.content_object.course.page.certificate_page.CEUs, } ], "order": { "id": order.id, "created_on": order.created_on, "reference_number": order.reference_number, }, "purchaser": { "first_name": purchaser.first_name, "last_name": purchaser.last_name, "email": order.purchaser.email, "country": purchaser.country, "state_or_territory": purchaser.state_or_territory, "city": purchaser.city, "postal_code": purchaser.postal_code, "company": order.purchaser.profile.company, "street_address": [ line for line in [ purchaser.street_address_1, purchaser.street_address_2, purchaser.street_address_3, purchaser.street_address_4, purchaser.street_address_5, ] if line ], }, "receipt": { "card_number": receipt_data["req_card_number"] if "req_card_number" in receipt_data else None, "card_type": CYBERSOURCE_CARD_TYPES[receipt_data["req_card_type"]] if "req_card_type" in receipt_data else None, "payment_method": receipt.data["req_payment_method"] if "req_payment_method" in receipt.data else None, "bill_to_email": receipt.data["req_bill_to_email"] if "req_bill_to_email" in receipt.data else None, "name": f"{receipt.data.get('req_bill_to_forename')} {receipt.data.get('req_bill_to_surname')}" if "req_bill_to_forename" in receipt.data or "req_bill_to_surname" in receipt.data else None, } if receipt else None, }
def test_order_audit(has_user, has_lines): """ Order.save_and_log() should save the order's information to an audit model. """ coupon_redemption = CouponRedemptionFactory.create() assert str(coupon_redemption ) == "CouponRedemption for order {}, coupon version {}".format( str(coupon_redemption.order), str(coupon_redemption.coupon_version)) order = coupon_redemption.order contents = [CourseRunFactory.create(), ProgramFactory.create()] lines = ([ LineFactory.create(order=order, product_version__product__content_object=content) for content in contents ] if has_lines else []) assert OrderAudit.objects.count() == 0 order.save_and_log(UserFactory.create() if has_user else None) assert OrderAudit.objects.count() == 1 order_audit = OrderAudit.objects.first() assert order_audit.order == order assert order_audit.data_after == { **serialize_model_object(order), "purchaser_email": order.purchaser.email, "lines": [{ **serialize_model_object(line), "product_version_info": { **serialize_model_object(line.product_version), "product_info": { **serialize_model_object(line.product_version.product), "content_type_string": str(line.product_version.product.content_type), "content_object": serialize_model_object( line.product_version.product.content_object), }, }, } for line in lines], "coupons": [{ **serialize_model_object(coupon_redemption.coupon_version.coupon), "coupon_version_info": { **serialize_model_object(coupon_redemption.coupon_version), "payment_version_info": serialize_model_object( coupon_redemption.coupon_version.payment_version), }, } for coupon_redemption in order.couponredemption_set.all()], "run_enrollments": [ enrollment.run.courseware_id for enrollment in order.courserunenrollment_set.all() ], "total_price": str( get_product_version_price_with_discount( product_version=lines[0].product_version, coupon_version=order.couponredemption_set.first(). coupon_version, )) if has_lines else "", "receipts": [ serialize_model_object(receipt) for receipt in order.receipt_set.all() ], }
def setUpTestData(cls): with mute_signals(post_save): cls.profile = profile = ProfileFactory.create() cls.user = profile.user EducationFactory.create(profile=profile) EmploymentFactory.create(profile=profile) # create a normal program program = ProgramFactory.create() cls.enrollments = cls._generate_cached_enrollments(cls.user, program, num_course_runs=2) certificate_grades_vals = [0.7, 0.8] cls.current_grades_vals = [0.9, 1.0] cls.certificates = [] cls.current_grades = [] for i, enrollment in enumerate(cls.enrollments): cls.certificates.append( CachedCertificateFactory.create( user=cls.user, course_run=enrollment.course_run, data={ "grade": certificate_grades_vals[i], "certificate_type": "verified", "course_id": enrollment.course_run.edx_course_key, "status": "downloadable", })) cls.current_grades.append( CachedCurrentGradeFactory.create( user=cls.user, course_run=enrollment.course_run, data={ "passed": True, "percent": cls.current_grades_vals[i], "course_key": enrollment.course_run.edx_course_key, })) FinalGradeFactory.create( user=cls.user, course_run=enrollment.course_run, grade=certificate_grades_vals[i], passed=True, ) non_fa_cached_edx_data = CachedEdxUserData(cls.user, program=program) non_fa_mmtrack = MMTrack(cls.user, program, non_fa_cached_edx_data) cls.serialized_enrollments = UserProgramSearchSerializer.serialize_enrollments( non_fa_mmtrack) cls.serialized_course_enrollments = UserProgramSearchSerializer.serialize_course_enrollments( non_fa_mmtrack) cls.semester_enrollments = UserProgramSearchSerializer.serialize_course_runs_enrolled( non_fa_mmtrack) cls.program_enrollment = ProgramEnrollment.objects.create( user=cls.user, program=program) # create a financial aid program cls.fa_program, _ = create_program() cls.fa_program_enrollment = ProgramEnrollment.objects.create( user=cls.user, program=cls.fa_program) cls.fa_enrollments = cls._generate_cached_enrollments( cls.user, cls.fa_program, num_course_runs=2) cls.current_grades = [] for i, enrollment in enumerate(cls.fa_enrollments): order = OrderFactory.create(user=cls.user, status='fulfilled') LineFactory.create(order=order, course_key=enrollment.course_run.edx_course_key) cls.current_grades.append( CachedCurrentGradeFactory.create( user=cls.user, course_run=enrollment.course_run, data={ "passed": True, "percent": cls.current_grades_vals[i], "course_key": enrollment.course_run.edx_course_key, })) FinalGradeFactory.create( user=cls.user, course_run=enrollment.course_run, grade=cls.current_grades_vals[i], passed=True, ) fa_cached_edx_data = CachedEdxUserData(cls.user, program=cls.fa_program) fa_mmtrack = MMTrack(cls.user, cls.fa_program, fa_cached_edx_data) cls.fa_serialized_course_enrollments = ( UserProgramSearchSerializer.serialize_course_enrollments( fa_mmtrack)) cls.fa_serialized_enrollments = ( UserProgramSearchSerializer.serialize_enrollments(fa_mmtrack))
def setUpTestData(cls): with mute_signals(post_save): cls.profile = profile = ProfileFactory.create() cls.user = profile.user EducationFactory.create(profile=profile) EmploymentFactory.create(profile=profile) # create a normal program program = ProgramFactory.create() cls.enrollments = cls._generate_cached_enrollments(cls.user, program, num_course_runs=2) certificate_grades_vals = [0.7, 0.8] cls.current_grades_vals = [0.9, 1.0] cls.certificates = [] cls.current_grades = [] for i, enrollment in enumerate(cls.enrollments): cls.certificates.append( CachedCertificateFactory.create( user=cls.user, course_run=enrollment.course_run, data={ "grade": certificate_grades_vals[i], "certificate_type": "verified", "course_id": enrollment.course_run.edx_course_key, "status": "downloadable", } ) ) cls.current_grades.append( CachedCurrentGradeFactory.create( user=cls.user, course_run=enrollment.course_run, data={ "passed": True, "percent": cls.current_grades_vals[i], "course_key": enrollment.course_run.edx_course_key, } ) ) FinalGradeFactory.create( user=cls.user, course_run=enrollment.course_run, grade=certificate_grades_vals[i], passed=True, ) non_fa_cached_edx_data = CachedEdxUserData(cls.user, program=program) non_fa_mmtrack = MMTrack(cls.user, program, non_fa_cached_edx_data) cls.serialized_enrollments = UserProgramSearchSerializer.serialize_enrollments(non_fa_mmtrack) cls.serialized_course_enrollments = UserProgramSearchSerializer.serialize_course_enrollments(non_fa_mmtrack) cls.semester_enrollments = UserProgramSearchSerializer.serialize_course_runs_enrolled(non_fa_mmtrack) cls.program_enrollment = ProgramEnrollment.objects.create(user=cls.user, program=program) # create a financial aid program cls.fa_program, _ = create_program() cls.fa_program_enrollment = ProgramEnrollment.objects.create(user=cls.user, program=cls.fa_program) cls.fa_enrollments = cls._generate_cached_enrollments(cls.user, cls.fa_program, num_course_runs=2) cls.current_grades = [] for i, enrollment in enumerate(cls.fa_enrollments): order = OrderFactory.create(user=cls.user, status='fulfilled') LineFactory.create(order=order, course_key=enrollment.course_run.edx_course_key) cls.current_grades.append( CachedCurrentGradeFactory.create( user=cls.user, course_run=enrollment.course_run, data={ "passed": True, "percent": cls.current_grades_vals[i], "course_key": enrollment.course_run.edx_course_key, } ) ) FinalGradeFactory.create( user=cls.user, course_run=enrollment.course_run, grade=cls.current_grades_vals[i], passed=True, ) fa_cached_edx_data = CachedEdxUserData(cls.user, program=cls.fa_program) fa_mmtrack = MMTrack(cls.user, cls.fa_program, fa_cached_edx_data) cls.fa_serialized_course_enrollments = ( UserProgramSearchSerializer.serialize_course_enrollments(fa_mmtrack) ) cls.fa_serialized_enrollments = ( UserProgramSearchSerializer.serialize_enrollments(fa_mmtrack) )
def test_order_str(self): """Test Order.__str__""" order = LineFactory.create().order assert str(order) == "Order {}, status={} for user={}".format(order.id, order.status, order.user)