def test_create_assignments_for_multi_use_per_customer(self, __): """ Verify the `create_assignments_for_multi_use_per_customer` works as expected for `MULTI_USE_PER_CUSTOMER`. """ coupon_max_global_applications = 10 enterprise_offer = EnterpriseOfferFactory( max_global_applications=coupon_max_global_applications) voucher = VoucherFactory(usage=Voucher.MULTI_USE_PER_CUSTOMER) voucher.offers.add(enterprise_offer) basket = create_basket(owner=self.user, site=self.site) basket.vouchers.add(voucher) order = create_order(user=self.user, basket=basket) assert OfferAssignment.objects.all().count() == 0 EdxOrderPlacementMixin().create_assignments_for_multi_use_per_customer( order) EdxOrderPlacementMixin().update_assigned_voucher_offer_assignment( order) assert OfferAssignment.objects.all().count( ) == coupon_max_global_applications assert OfferAssignment.objects.filter( offer=enterprise_offer, code=voucher.code, user_email=basket.owner.email, status=OFFER_ASSIGNED).count() == 9 assert OfferAssignment.objects.filter( offer=enterprise_offer, code=voucher.code, user_email=basket.owner.email, status=OFFER_REDEEMED).count() == 1
def test_create_offer_assignments_for_updated_max_uses(self, __): """ Verify the `create_assignments_for_multi_use_per_customer` works as expected for `MULTI_USE_PER_CUSTOMER` when `max_global_applications` is updated for existing voucher. """ coupon_max_global_applications = 1 enterprise_offer = EnterpriseOfferFactory( max_global_applications=coupon_max_global_applications) voucher = VoucherFactory(usage=Voucher.MULTI_USE_PER_CUSTOMER) voucher.offers.add(enterprise_offer) basket = create_basket(owner=self.user, site=self.site) basket.vouchers.add(voucher) order = create_order(user=self.user, basket=basket) assert OfferAssignment.objects.all().count() == 0 EdxOrderPlacementMixin().create_assignments_for_multi_use_per_customer( order) EdxOrderPlacementMixin().update_assigned_voucher_offer_assignment( order) assert OfferAssignment.objects.all().count( ) == coupon_max_global_applications assert OfferAssignment.objects.filter( offer=enterprise_offer, code=voucher.code, user_email=basket.owner.email, status=OFFER_REDEEMED).count() == 1 # update max_global_applications coupon_new_max_global_applications = 5 enterprise_offer.max_global_applications = coupon_new_max_global_applications enterprise_offer.save() assert voucher.enterprise_offer.max_global_applications == coupon_new_max_global_applications EdxOrderPlacementMixin().create_assignments_for_multi_use_per_customer( order) assert OfferAssignment.objects.all().count( ) == coupon_new_max_global_applications assert OfferAssignment.objects.filter( offer=enterprise_offer, code=voucher.code, user_email=basket.owner.email, status=OFFER_ASSIGNED).count() == 4 assert OfferAssignment.objects.filter( offer=enterprise_offer, code=voucher.code, user_email=basket.owner.email, status=OFFER_REDEEMED).count() == 1 # call once again to verify nothing is created because all available slots are assigned EdxOrderPlacementMixin().create_assignments_for_multi_use_per_customer( order) assert OfferAssignment.objects.all().count( ) == coupon_new_max_global_applications
def create_vouchers(self, partner=None, count=1): """Helper function that creates vouchers with a mocked coupon relation.""" vouchers = VoucherFactory.create_batch(count) partner = partner or self.partner coupon_vouchers = CouponVouchers.objects.create(coupon=ProductFactory( stockrecords__partner=partner)) for voucher in vouchers: voucher.offers.add(ConditionalOfferFactory()) coupon_vouchers.vouchers.add(voucher) return vouchers
def test_list_with_code_filter(self): """ Verify the endpoint list all vouchers, filtered by the specified code. """ voucher = VoucherFactory() voucher.offers.add(ConditionalOfferFactory()) url = '{path}?code={code}'.format(path=self.path, code=voucher.code) response = self.client.get(url) self.assertEqual(response.data['count'], 1) self.assertEqual(response.data['results'][0]['code'], voucher.code)
def setUp(self): """ Setup the test data """ super(SendCodeAssignmentNudgeEmailsTests, self).setUp() # Create a voucher with valid offer so we can get self.voucher = VoucherFactory() self.voucher.offers.add( EnterpriseOfferFactory(max_global_applications=98)) self.total_nudge_emails_for_today = 5 self.nudge_emails = CodeAssignmentNudgeEmailsFactory.create_batch( self.total_nudge_emails_for_today, code=self.voucher.code) CodeAssignmentNudgeEmailsFactory(email_date=datetime.datetime.now() + relativedelta(days=1)) CodeAssignmentNudgeEmailsFactory(email_date=datetime.datetime.now() + relativedelta(days=2)) for nudge_email in self.nudge_emails: OfferAssignmentFactory(code=nudge_email.code, user_email=nudge_email.user_email)
def test_list(self): """ Verify the endpoint lists all vouchers. """ vouchers = VoucherFactory.create_batch(3) for voucher in vouchers: voucher.offers.add(ConditionalOfferFactory()) response = self.client.get(self.path) self.assertEqual(response.data['count'], len(vouchers)) actual_codes = [datum['code'] for datum in response.data['results']] expected_codes = [voucher.code for voucher in vouchers] self.assertEqual(actual_codes, expected_codes)
def test_update_assigned_voucher_offer_assignment(self, __): """ Verify the "update_assigned_voucher_offer_assignment" works as expected. """ enterprise_offer = EnterpriseOfferFactory() voucher = VoucherFactory() voucher.offers.add(enterprise_offer) basket = create_basket(owner=self.user, site=self.site) basket.vouchers.add(voucher) order = create_order(user=self.user, basket=basket) voucher_application = VoucherApplication.objects.create(voucher=voucher, user=self.user, order=order) offer_assignment = OfferAssignmentFactory(offer=enterprise_offer, code=voucher.code, user_email=self.user.email) EdxOrderPlacementMixin().update_assigned_voucher_offer_assignment(order) offer_assignment = OfferAssignment.objects.get(id=offer_assignment.id) assert offer_assignment.status == OFFER_REDEEMED assert offer_assignment.voucher_application == voucher_application
def test_get_course_offer_data(self): """ Verify that the course offers data is properly formatted. """ benefit = BenefitFactory() course, seat = self.create_course_and_seat() course_info = { 'start': '2016-05-01T00:00:00Z', 'image': { 'src': 'path/to/the/course/image' } } stock_record = seat.stockrecords.first() voucher = VoucherFactory() offer = VoucherViewSet().get_course_offer_data( benefit=benefit, course=course, course_info=course_info, credit_provider_price=None, multiple_credit_providers=False, is_verified=True, product=seat, stock_record=stock_record, voucher=voucher) self.assertDictEqual( offer, { 'benefit': { 'type': get_benefit_type(benefit), 'value': benefit.value }, 'contains_verified': True, 'course_start_date': course_info['start'], 'id': course.id, 'image_url': course_info['image']['src'], 'multiple_credit_providers': False, 'organization': CourseKey.from_string(course.id).org, 'credit_provider_price': None, 'seat_type': seat.attr.certificate_type, 'stockrecords': serializers.StockRecordSerializer(stock_record).data, 'title': course.name, 'voucher_end_date': voucher.end_datetime, })
def test_update_assigned_voucher_offer_assignment(self, __): """ Verify the "update_assigned_voucher_offer_assignment" works as expected. """ enterprise_offer = EnterpriseOfferFactory() voucher = VoucherFactory() voucher.offers.add(enterprise_offer) basket = create_basket(owner=self.user, site=self.site) basket.vouchers.add(voucher) order = create_order(user=self.user, basket=basket) voucher_application = VoucherApplication.objects.create( voucher=voucher, user=self.user, order=order) offer_assignment = OfferAssignmentFactory(offer=enterprise_offer, code=voucher.code, user_email=self.user.email) # create nudge email templates and subscription records for email_type in (DAY3, DAY10, DAY19): nudge_email_template = CodeAssignmentNudgeEmailTemplatesFactory( email_type=email_type) nudge_email = CodeAssignmentNudgeEmailsFactory( email_template=nudge_email_template, user_email=self.user.email, code=voucher.code) # verify subscription is active assert nudge_email.is_subscribed EdxOrderPlacementMixin().update_assigned_voucher_offer_assignment( order) offer_assignment = OfferAssignment.objects.get(id=offer_assignment.id) assert offer_assignment.status == OFFER_REDEEMED assert offer_assignment.voucher_application == voucher_application # verify that nudge emails subscriptions are inactive assert CodeAssignmentNudgeEmails.objects.filter( is_subscribed=True).count() == 0 assert CodeAssignmentNudgeEmails.objects.filter( code__in=[voucher.code], user_email__in=[self.user.email], is_subscribed=False).count() == 3
def test_get_course_offer_verify_null_fields(self): """ Verify that the course offers data is properly formatted. """ benefit = BenefitFactory() course, seat = self.create_course_and_seat() course_info = { 'start': None, 'image': None, } stock_record = seat.stockrecords.first() voucher = VoucherFactory() offer = VoucherViewSet().get_course_offer_data( benefit=benefit, course=course, course_info=course_info, credit_provider_price=None, is_verified=True, multiple_credit_providers=False, product=seat, stock_record=stock_record, voucher=voucher) self.assertEqual(offer['image_url'], '') self.assertEqual(offer['course_start_date'], None)
class SendCodeAssignmentNudgeEmailsTests(TestCase): """ Tests the sending code assignment nudge emails command. """ def setUp(self): """ Setup the test data """ super(SendCodeAssignmentNudgeEmailsTests, self).setUp() # Create a voucher with valid offer so we can get self.voucher = VoucherFactory() self.voucher.offers.add( EnterpriseOfferFactory(max_global_applications=98)) self.total_nudge_emails_for_today = 5 self.nudge_emails = CodeAssignmentNudgeEmailsFactory.create_batch( self.total_nudge_emails_for_today, code=self.voucher.code) CodeAssignmentNudgeEmailsFactory(email_date=datetime.datetime.now() + relativedelta(days=1)) CodeAssignmentNudgeEmailsFactory(email_date=datetime.datetime.now() + relativedelta(days=2)) for nudge_email in self.nudge_emails: OfferAssignmentFactory(code=nudge_email.code, user_email=nudge_email.user_email) def assert_last_reminder_date(self): current_date_time = timezone.now() for offer_assignment in OfferAssignment.objects.all(): assert offer_assignment.last_reminder_date.date( ) == current_date_time.date() def _assert_sent_count(self): nudge_email = CodeAssignmentNudgeEmails.objects.all() assert nudge_email.filter(already_sent=True).count() == 0 cmd_path = 'ecommerce.enterprise.management.commands.send_code_assignment_nudge_emails' with mock.patch( cmd_path + '.send_code_assignment_nudge_email.delay') as mock_send_email: with LogCapture(level=logging.INFO) as log: mock_send_email.return_value = mock.Mock() call_command('send_code_assignment_nudge_emails') assert mock_send_email.call_count == self.total_nudge_emails_for_today assert nudge_email.filter(already_sent=True).count( ) == self.total_nudge_emails_for_today return log def test_command(self): """ Test the send_enterprise_offer_limit_emails command """ log = self._assert_sent_count() self.assert_last_reminder_date() log.check_present(( LOGGER_NAME, 'INFO', '[Code Assignment Nudge Email] Total count of Enterprise Nudge Emails that are scheduled for ' 'today is {send_nudge_email_count}.'.format( send_nudge_email_count=self.total_nudge_emails_for_today) ), (LOGGER_NAME, 'INFO', '[Code Assignment Nudge Email] {send_nudge_emails_count} out of {total_nudge_emails} added to the ' 'email sending queue.'.format( total_nudge_emails=self.total_nudge_emails_for_today, send_nudge_emails_count=self.total_nudge_emails_for_today))) def test_nudge_email_command_with_invalid_code(self): """ Test the send_enterprise_offer_limit_emails command """ code = "dummy-code" CodeAssignmentNudgeEmailsFactory(code=code) log = self._assert_sent_count() log.check_present(( LOGGER_NAME, 'INFO', '[Code Assignment Nudge Email] Total count of Enterprise Nudge Emails that are scheduled for ' 'today is {send_nudge_email_count}.'.format( send_nudge_email_count=self.total_nudge_emails_for_today + 1) ), (LOGGER_NAME, 'INFO', '[Code Assignment Nudge Email] {send_nudge_emails_count} out of {total_nudge_emails} added to the ' 'email sending queue.'.format( total_nudge_emails=self.total_nudge_emails_for_today + 1, send_nudge_emails_count=self.total_nudge_emails_for_today))) def test_nudge_email_sent_record_created(self): """ Test that an instance of OfferAssignmentEmailSentRecord is created when a nudge email is sent. """ # Check that no email record exists yet assert OfferAssignmentEmailSentRecord.objects.count() == 0 self._assert_sent_count() # Check that a new email record for every email has been created now that the nudge emails are sent assert OfferAssignmentEmailSentRecord.objects.count( ) == self.total_nudge_emails_for_today def test_nudge_email_with_expired_voucher(self): """ Test that no nudge email is sent when voucher is expired and user is unsubscribed from receiving email. """ self.voucher.end_datetime = datetime.datetime.now( pytz.UTC) - datetime.timedelta(days=1) self.voucher.save(update_fields=['end_datetime']) nudge_email = CodeAssignmentNudgeEmails.objects.all() cmd_path = 'ecommerce.enterprise.management.commands.send_code_assignment_nudge_emails' with mock.patch( cmd_path + '.send_code_assignment_nudge_email.delay') as mock_send_email: mock_send_email.return_value = mock.Mock() call_command('send_code_assignment_nudge_emails') # assert that no emails were sent assert mock_send_email.call_count == 0 assert nudge_email.filter(already_sent=True).count() == 0 # assert that nudge emails are unsubscribed if voucher is expired assert nudge_email.filter(is_subscribed=False).count( ) == self.total_nudge_emails_for_today