def test_renewal_future_plan_auto_applies_licenses( self, should_auto_apply_licenses): customer_agreement = CustomerAgreementFactory.create() prior_plan = SubscriptionPlanFactory( customer_agreement=customer_agreement, should_auto_apply_licenses=should_auto_apply_licenses) renewal = SubscriptionPlanRenewalFactory( prior_subscription_plan=prior_plan, number_of_licenses=1, license_types_to_copy=constants.LicenseTypesToRenew. ASSIGNED_AND_ACTIVATED, effective_date=NOW) with freezegun.freeze_time(NOW): api.renew_subscription(renewal) renewal.refresh_from_db() future_plan = renewal.renewed_subscription_plan if should_auto_apply_licenses: self.assertTrue(future_plan.should_auto_apply_licenses) self.assertEqual(customer_agreement.auto_applicable_subscription, future_plan) else: assert future_plan.should_auto_apply_licenses is None assert customer_agreement.auto_applicable_subscription is None
def handle(self, *args, **options): now = localized_utcnow() renewal_processing_window_cutoff = now + timedelta(hours=int(options['processing_window_length_hours'])) renewals_to_be_processed = SubscriptionPlanRenewal.objects.filter( effective_date__gte=now, effective_date__lte=renewal_processing_window_cutoff, processed=False ).select_related( 'prior_subscription_plan', 'prior_subscription_plan__customer_agreement', 'renewed_subscription_plan' ) subscription_uuids = [str(renewal.prior_subscription_plan.uuid) for renewal in renewals_to_be_processed] if not options['dry_run']: logger.info('Processing {} renewals for subscriptions with uuids: {}'.format( len(subscription_uuids), subscription_uuids)) renewed_subscription_uuids = [] for renewal in renewals_to_be_processed: subscription_uuid = str(renewal.prior_subscription_plan.uuid) try: renew_subscription(renewal, is_auto_renewed=True) renewed_subscription_uuids.append(subscription_uuid) except RenewalProcessingError: logger.error('Could not automatically process renewal with id: {}'.format( renewal.id), exc_info=True) logger.info('Processed {} renewals for subscriptions with uuids: {}'.format( len(renewed_subscription_uuids), renewed_subscription_uuids)) else: logger.info('Dry-run result subscriptions that would be renewed: {} '.format( subscription_uuids))
def test_renewal_processed_with_no_existing_future_plan(self): prior_plan = SubscriptionPlanFactory() original_activated_licenses = [ LicenseFactory.create( subscription_plan=prior_plan, status=constants.ACTIVATED, user_email='activated_user_{}@example.com'.format(i)) for i in range(5) ] original_assigned_licenses = [ LicenseFactory.create( subscription_plan=prior_plan, status=constants.ASSIGNED, user_email='assigned_user_{}@example.com'.format(i)) for i in range(5) ] original_licenses = original_activated_licenses + original_assigned_licenses renewal = SubscriptionPlanRenewalFactory( prior_subscription_plan=prior_plan, number_of_licenses=10, license_types_to_copy=constants.LicenseTypesToRenew. ASSIGNED_AND_ACTIVATED) with freezegun.freeze_time(NOW): api.renew_subscription(renewal) renewal.refresh_from_db() original_plan = renewal.prior_subscription_plan future_plan = renewal.renewed_subscription_plan self.assertTrue(renewal.processed) self.assertEqual(renewal.processed_datetime, NOW) self.assertEqual(original_plan.product_id, future_plan.product_id) self.assertEqual(future_plan.num_licenses, renewal.number_of_licenses) self._assert_all_licenses_renewed(future_plan)
def test_cannot_renew_too_many_existing_unassigned_licenses(self): future_plan = SubscriptionPlanFactory() LicenseFactory.create_batch( 50, subscription_plan=future_plan, status=constants.UNASSIGNED, ) renewal = SubscriptionPlanRenewalFactory( renewed_subscription_plan=future_plan, number_of_licenses=20, ) expected_message = 'More licenses exist than were requested to be renewed' with self.assertRaisesRegex(exceptions.RenewalProcessingError, expected_message): api.renew_subscription(renewal)
def test_cannot_renew_with_existing_assigned_future_licenses(self): future_plan = SubscriptionPlanFactory() LicenseFactory.create_batch( 5, subscription_plan=future_plan, status=constants.ACTIVATED, ) renewal = SubscriptionPlanRenewalFactory( renewed_subscription_plan=future_plan, number_of_licenses=20, ) expected_message = 'there are existing licenses in the renewed plan that are activated' with self.assertRaisesRegex(exceptions.RenewalProcessingError, expected_message): api.renew_subscription(renewal)
def test_cannot_renew_for_fewer_licenses(self): prior_plan = SubscriptionPlanFactory() LicenseFactory.create_batch( 5, subscription_plan=prior_plan, status=constants.ACTIVATED, ) renewal = SubscriptionPlanRenewalFactory( number_of_licenses=2, prior_subscription_plan=prior_plan, ) expected_message = 'Cannot renew for fewer than the number of original activated licenses.' with self.assertRaisesRegex(exceptions.RenewalProcessingError, expected_message): api.renew_subscription(renewal)
def test_renewal_disable_auto_apply_licenses(self): customer_agreement = CustomerAgreementFactory.create() prior_plan = SubscriptionPlanFactory( customer_agreement=customer_agreement, should_auto_apply_licenses=True) renewal = SubscriptionPlanRenewalFactory( prior_subscription_plan=prior_plan, number_of_licenses=1, license_types_to_copy=constants.LicenseTypesToRenew. ASSIGNED_AND_ACTIVATED, disable_auto_apply_licenses=True) with freezegun.freeze_time(NOW): api.renew_subscription(renewal) future_plan = renewal.renewed_subscription_plan self.assertFalse(future_plan.should_auto_apply_licenses) assert customer_agreement.auto_applicable_subscription is None
def test_license_renewed_events(self): """ Test that our standard renewal routine triggers the right set of events for all licenses involved: - a creation event for each new license - NO assignment or activation event since the license comes from a renewal. - a renewal event for each old/new license pair """ prior_plan = SubscriptionPlanFactory() original_activated_licenses = [ LicenseFactory.create( subscription_plan=prior_plan, status=constants.ACTIVATED, user_email='activated_user_{}@example.com'.format(i)) for i in range(2) ] original_assigned_licenses = [ LicenseFactory.create( subscription_plan=prior_plan, status=constants.ASSIGNED, user_email='assigned_user_{}@example.com'.format(i)) for i in range(2) ] original_licenses = original_activated_licenses + original_assigned_licenses renewal = SubscriptionPlanRenewalFactory( prior_subscription_plan=prior_plan, number_of_licenses=len(original_licenses), license_types_to_copy=constants.LicenseTypesToRenew. ASSIGNED_AND_ACTIVATED) with mock.patch( 'license_manager.apps.subscriptions.event_utils.track_event' ) as mock_track_event: with freeze_time(NOW): api.renew_subscription(renewal) renewal.refresh_from_db() for call in mock_track_event.call_args_list[0:4]: assert call[0][1] == constants.SegmentEvents.LICENSE_CREATED for call in mock_track_event.call_args_list[4:]: assert call[0][1] == constants.SegmentEvents.LICENSE_RENEWED assert mock_track_event.call_count == 8
def test_renewal_processed_segment_events(self, mock_track_event): prior_plan = SubscriptionPlanFactory() [ LicenseFactory.create(subscription_plan=prior_plan, status=constants.ACTIVATED, user_email='activated_user_{}@example.com') ] renewal = SubscriptionPlanRenewalFactory( prior_subscription_plan=prior_plan, number_of_licenses=1, license_types_to_copy=constants.LicenseTypesToRenew. ASSIGNED_AND_ACTIVATED) api.renew_subscription(renewal) assert mock_track_event.call_count == 2 assert (mock_track_event.call_args_list[0].args[1] == constants.SegmentEvents.LICENSE_CREATED) assert (mock_track_event.call_args_list[1].args[1] == constants.SegmentEvents.LICENSE_RENEWED) self.assertFalse( mock_track_event.call_args_list[1].args[2]['is_auto_renewed'])
def test_renewal_processed_with_existing_future_plan(self): prior_plan = SubscriptionPlanFactory() original_licenses = [ LicenseFactory.create( subscription_plan=prior_plan, status=constants.ACTIVATED, user_email='activated_user_{}@example.com'.format(i)) for i in range(5) ] # create some revoked original licenses that should not be renewed LicenseFactory.create_batch( 67, subscription_plan=prior_plan, status=constants.REVOKED, ) future_plan = SubscriptionPlanFactory() LicenseFactory.create_batch( 10, subscription_plan=future_plan, status=constants.UNASSIGNED, ) renewal = SubscriptionPlanRenewalFactory( prior_subscription_plan=prior_plan, renewed_subscription_plan=future_plan, number_of_licenses=10, ) with freezegun.freeze_time(NOW): api.renew_subscription(renewal) future_plan.refresh_from_db() self.assertTrue(renewal.processed) self.assertEqual(renewal.processed_datetime, NOW) self.assertEqual(future_plan.num_licenses, renewal.number_of_licenses) self._assert_all_licenses_renewed(future_plan)
def process_renewal(self, request, queryset): for renewal in queryset: renew_subscription(renewal)