diff --git a/backend/src/accounts/admin.py b/backend/src/accounts/admin.py index dd3459152..09514d93c 100644 --- a/backend/src/accounts/admin.py +++ b/backend/src/accounts/admin.py @@ -742,8 +742,6 @@ def save_model(self, request, obj, form, change): with transaction.atomic(): if obj.billing_plan == BillingPlanType.PREMIUM: max_users = obj.get_paid_users_count() - elif obj.billing_plan == BillingPlanType.FREEMIUM: - max_users = settings.DEFAULT_MAX_USERS else: max_users = 1000 obj = service.partial_update( diff --git a/backend/src/accounts/services/account.py b/backend/src/accounts/services/account.py index 1f0b0a2d2..5a21f318c 100644 --- a/backend/src/accounts/services/account.py +++ b/backend/src/accounts/services/account.py @@ -50,9 +50,6 @@ def _create_tenant( tenant_name: str, ) -> Account: - billing_enabled = ( - settings.PROJECT_CONF['BILLING'] and master_account.billing_sync - ) account = Account( is_verified=True, name='Company name', @@ -77,7 +74,7 @@ def _create_tenant( ): account.billing_plan = BillingPlanType.FREEMIUM elif master_account.billing_plan == BillingPlanType.UNLIMITED: - if billing_enabled: + if master_account.billing_sync: # Need buy account.billing_plan = None else: @@ -97,7 +94,7 @@ def _create_instance( name: Optional[str] = None, tenant_name: Optional[str] = None, master_account: Optional[Account] = None, - billing_sync: bool = True, + billing_sync: bool = settings.PROJECT_CONF['BILLING'], **kwargs, ) -> Account: @@ -107,13 +104,12 @@ def _create_instance( tenant_name=tenant_name, ) else: - billing_enabled = settings.PROJECT_CONF['BILLING'] and billing_sync self.instance = Account( is_verified=is_verified, name=name or 'Company name', billing_sync=billing_sync, ) - if not billing_enabled: + if not billing_sync: self.instance.billing_plan = BillingPlanType.FREEMIUM self.instance.billing_sync = False self.instance.save() @@ -286,7 +282,7 @@ def partial_update( ], ) self._update_tenants() - if settings.PROJECT_CONF['BILLING'] and self.instance.billing_sync: + if self.instance.billing_sync: self._update_stripe_account(**update_kwargs) self._identify_users() self.group(user=self.user, account=self.instance) diff --git a/backend/src/accounts/services/convert_account.py b/backend/src/accounts/services/convert_account.py index 9c0c3b627..6fd6cee4d 100644 --- a/backend/src/accounts/services/convert_account.py +++ b/backend/src/accounts/services/convert_account.py @@ -1,6 +1,5 @@ from typing import Optional -from django.conf import settings from django.contrib.auth import get_user_model from src.accounts.enums import ( @@ -59,7 +58,7 @@ def _standard_to_tenant(self): ) master_account = self.instance.master_account billing_enabled = ( - settings.PROJECT_CONF['BILLING'] and master_account.billing_sync + master_account.billing_sync ) update_kwargs = { 'logo_lg': master_account.logo_lg, diff --git a/backend/src/accounts/services/user_invite.py b/backend/src/accounts/services/user_invite.py index 460d093e5..462b38f23 100644 --- a/backend/src/accounts/services/user_invite.py +++ b/backend/src/accounts/services/user_invite.py @@ -446,8 +446,7 @@ def accept( ) account_service.update_users_counts() if ( - settings.PROJECT_CONF['BILLING'] - and user.account.billing_sync + user.account.billing_sync and user.account.billing_plan == BillingPlanType.PREMIUM ): increase_plan_users.delay( diff --git a/backend/src/accounts/services/user_transfer.py b/backend/src/accounts/services/user_transfer.py index a6dd210a9..dc15857d2 100644 --- a/backend/src/accounts/services/user_transfer.py +++ b/backend/src/accounts/services/user_transfer.py @@ -1,4 +1,3 @@ -from django.conf import settings from django.contrib.auth import get_user_model from django.db import transaction from rest_framework_simplejwt.exceptions import TokenError @@ -80,8 +79,7 @@ def _get_valid_token(self, token_str: str) -> TransferToken: def _after_transfer_actions(self): if ( - settings.PROJECT_CONF['BILLING'] - and self.user.account.billing_sync + self.user.account.billing_sync and self.user.account.billing_plan == BillingPlanType.PREMIUM ): increase_plan_users.delay( @@ -134,8 +132,7 @@ def _deactivate_prev_user(self): ) self._delete_prev_user_pending_invites() if ( - settings.PROJECT_CONF['BILLING'] - and self.prev_user.account.billing_sync + self.prev_user.account.billing_sync and self.prev_user.is_account_owner and self.prev_user.account.billing_plan in BillingPlanType.PAYMENT_PLANS diff --git a/backend/src/accounts/tests/services/test_account.py b/backend/src/accounts/tests/services/test_account.py index df8ad0fed..dae77718d 100644 --- a/backend/src/accounts/tests/services/test_account.py +++ b/backend/src/accounts/tests/services/test_account.py @@ -38,10 +38,6 @@ def test_create_tenant__master_account_on_premium__inherit_plan( ): # arrange - settings_mock = mocker.patch( - 'src.accounts.services.account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} trial_start = timezone.now() - timedelta(days=30) trial_end = timezone.now() - timedelta(days=23) trial_ended = True @@ -90,10 +86,6 @@ def test_create_tenant__master_account_on_fractionalcoo__set_plan_freemium( ): # arrange - settings_mock = mocker.patch( - 'src.accounts.services.account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} trial_start = timezone.now() - timedelta(days=30) trial_end = timezone.now() - timedelta(days=23) trial_ended = True @@ -142,10 +134,6 @@ def test_create_tenant__master_account_on_freemium__set_plan_freemium( ): # arrange - settings_mock = mocker.patch( - 'src.accounts.services.account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} master_account = create_test_account( logo_lg='https://some.logo/image1.png', logo_sm='https://some.logo/image2.png', @@ -189,10 +177,6 @@ def test_create_tenant__master_account_on_freemium__set_plan_freemium( def test_create_tenant__master_account_on_unlimited__set_plan_is_null(mocker): # arrange - settings_mock = mocker.patch( - 'src.accounts.services.account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} trial_start = timezone.now() - timedelta(days=30) trial_end = timezone.now() - timedelta(days=23) trial_ended = True @@ -235,16 +219,7 @@ def test_create_tenant__master_account_on_unlimited__set_plan_is_null(mocker): assert tenant_account.trial_end is None assert tenant_account.trial_ended is False - -def test_create_tenant__master_account_on_unlimited_bs_disabled__inherit_plan( - mocker, -): - # arrange - settings_mock = mocker.patch( - 'src.accounts.services.account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': False} trial_ended = True master_account = create_test_account( logo_lg='https://some.logo/image1.png', @@ -273,15 +248,15 @@ def test_create_tenant__master_account_on_unlimited_bs_disabled__inherit_plan( assert tenant_account.lease_level == LeaseLevel.TENANT assert tenant_account.logo_lg == master_account.logo_lg assert tenant_account.logo_sm == master_account.logo_sm - assert tenant_account.max_users == master_account.max_users - assert tenant_account.billing_sync == master_account.billing_sync + assert tenant_account.max_users == 1000 + assert tenant_account.billing_sync is True - assert tenant_account.billing_plan == master_account.billing_plan - assert tenant_account.billing_period == master_account.billing_period - assert tenant_account.plan_expiration == master_account.plan_expiration - assert tenant_account.trial_start == master_account.trial_start - assert tenant_account.trial_end == master_account.trial_end - assert tenant_account.trial_ended == trial_ended + assert tenant_account.billing_plan is None + assert tenant_account.billing_period is None + assert tenant_account.plan_expiration is None + assert tenant_account.trial_start is None + assert tenant_account.trial_end is None + assert tenant_account.trial_ended is False def test_create_instance__tenant__ok(mocker): @@ -318,10 +293,6 @@ def test_create_instance__ok(mocker): 'src.accounts.services.account.AccountService.' '_create_tenant', ) - settings_mock = mocker.patch( - 'src.accounts.services.account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} company_name = 'Name' service = AccountService() @@ -377,10 +348,6 @@ def test_create_instance__disable_billing_sync__set_freemium_plan(mocker): 'src.accounts.services.account.AccountService.' '_create_tenant', ) - settings_mock = mocker.patch( - 'src.accounts.services.account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} company_name = 'Company' service = AccountService() @@ -405,41 +372,6 @@ def test_create_instance__disable_billing_sync__set_freemium_plan(mocker): create_tenant_mock.assert_not_called() -def test_create_instance__disable_global_billing__set_freemium_plan(mocker): - - # arrange - create_tenant_mock = mocker.patch( - 'src.accounts.services.account.AccountService.' - '_create_tenant', - ) - settings_mock = mocker.patch( - 'src.accounts.services.account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': False} - company_name = 'Company' - service = AccountService() - - # act - account = service._create_instance( - is_verified=False, - name=company_name, - billing_sync=True, - ) - - # assert - assert account.id - assert account.billing_sync is False - assert account.name == company_name - assert account.is_verified is False - assert account.billing_plan == BillingPlanType.FREEMIUM - assert account.billing_period is None - assert account.plan_expiration is None - assert account.trial_start is None - assert account.trial_end is None - assert account.trial_ended is False - create_tenant_mock.assert_not_called() - - def test_create_related__not_utm__ok(): # arrange @@ -803,10 +735,6 @@ def test_partial_update__ok(mocker): instance=account, user=user, ) - settings_mock = mocker.patch( - 'src.accounts.services.account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} group_mock = mocker.patch( 'src.analysis.mixins.BaseIdentifyMixin.group', ) @@ -900,62 +828,6 @@ def test_partial_update__disabled_billing_sync__ok(mocker): instance=account, user=user, ) - settings_mock = mocker.patch( - 'src.accounts.services.account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} - group_mock = mocker.patch( - 'src.analysis.mixins.BaseIdentifyMixin.group', - ) - update_stripe_account_mock = mocker.patch( - 'src.accounts.services.account.' - 'AccountService._update_stripe_account', - ) - update_tenants_mock = mocker.patch( - 'src.accounts.services.account.' - 'AccountService._update_tenants', - ) - identify_users_mock = mocker.patch( - 'src.accounts.services.account.' - 'AccountService._identify_users', - ) - - # act - result = service.partial_update( - name=name, - logo_lg=logo_lg, - logo_sm=logo_sm, - force_save=True, - ) - - # assert - account.refresh_from_db() - assert result.id == account.id - assert account.logo_lg == logo_lg - assert account.logo_sm == logo_sm - assert account.name == name - update_tenants_mock.assert_called_once() - update_stripe_account_mock.assert_not_called() - identify_users_mock.assert_called_once() - group_mock.assert_called_once_with(user=user, account=account) - - -def test_partial_update__disabled_billing__ok(mocker): - - # arrange - account = create_test_account(lease_level=LeaseLevel.STANDARD) - user = create_test_user(account=account) - logo_lg = 'http://site.com/logo_lg.img' - logo_sm = 'http://site.com/logo_sm.img' - name = 'New account name' - service = AccountService( - instance=account, - user=user, - ) - settings_mock = mocker.patch( - 'src.accounts.services.account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': False} group_mock = mocker.patch( 'src.analysis.mixins.BaseIdentifyMixin.group', ) diff --git a/backend/src/accounts/tests/services/test_convert_account.py b/backend/src/accounts/tests/services/test_convert_account.py index f74d48b2e..682f09a54 100644 --- a/backend/src/accounts/tests/services/test_convert_account.py +++ b/backend/src/accounts/tests/services/test_convert_account.py @@ -158,10 +158,6 @@ def test_standard_to_tenant__master_account_on_premium__inherit_plan( master_account=master_account, ) tenant_user = create_test_user(account=tenant_account) - settings_mock = mocker.patch( - 'src.accounts.services.convert_account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} update_master_account_user_counts_mock = mocker.patch( 'src.accounts.services.convert_account' '.AccountLLConverter._update_master_account_user_counts', @@ -257,10 +253,6 @@ def test_standard_to_tenant__master_account_on_premium_disable_billing__ok( master_account=master_account, ) tenant_user = create_test_user(account=tenant_account) - settings_mock = mocker.patch( - 'src.accounts.services.convert_account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} update_master_account_user_counts_mock = mocker.patch( 'src.accounts.services.convert_account' '.AccountLLConverter._update_master_account_user_counts', @@ -358,10 +350,6 @@ def test_standard_to_tenant__master_account_on_unlimited__buy_tenant_subs( master_account=master_account, ) tenant_user = create_test_user(account=tenant_account) - settings_mock = mocker.patch( - 'src.accounts.services.convert_account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} update_master_account_user_counts_mock = mocker.patch( 'src.accounts.services.convert_account' '.AccountLLConverter._update_master_account_user_counts', @@ -466,10 +454,6 @@ def test_standard_to_tenant__master_acc_on_unlimited__disable_billing__ok( master_account=master_account, ) tenant_user = create_test_user(account=tenant_account) - settings_mock = mocker.patch( - 'src.accounts.services.convert_account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} update_master_account_user_counts_mock = mocker.patch( 'src.accounts.services.convert_account' '.AccountLLConverter._update_master_account_user_counts', @@ -567,10 +551,6 @@ def test_standard_to_tenant__master_acc_on_fractionalcoo__ok( master_account=master_account, ) tenant_user = create_test_user(account=tenant_account) - settings_mock = mocker.patch( - 'src.accounts.services.convert_account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} update_master_account_user_counts_mock = mocker.patch( 'src.accounts.services.convert_account' '.AccountLLConverter._update_master_account_user_counts', @@ -652,10 +632,6 @@ def test_standard_to_tenant__master_acc_on_freemium__ok( master_account=master_account, ) tenant_user = create_test_user(account=tenant_account) - settings_mock = mocker.patch( - 'src.accounts.services.convert_account.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} update_master_account_user_counts_mock = mocker.patch( 'src.accounts.services.convert_account' '.AccountLLConverter._update_master_account_user_counts', diff --git a/backend/src/accounts/tests/services/test_invite.py b/backend/src/accounts/tests/services/test_invite.py index 8f70bb6a6..a486c8c42 100644 --- a/backend/src/accounts/tests/services/test_invite.py +++ b/backend/src/accounts/tests/services/test_invite.py @@ -1874,13 +1874,9 @@ def test__accept__all_fields__ok(identify_mock, group_mock, mocker): users_joined_mock = mocker.patch( 'src.accounts.services.user_invite.AnalyticService.users_joined', ) - settings_mock = mocker.patch( - 'src.accounts.services.user_invite.settings', - ) send_user_updated_mock = mocker.patch( 'src.notifications.tasks.send_user_updated_notification.delay', ) - settings_mock.PROJECT_CONF = {'BILLING': True} first_name = 'John' last_name = 'Wick' language = Language.fr @@ -1990,13 +1986,9 @@ def test__accept__only_required_fields__ok(identify_mock, group_mock, mocker): users_joined_mock = mocker.patch( 'src.accounts.services.user_invite.AnalyticService.users_joined', ) - settings_mock = mocker.patch( - 'src.accounts.services.user_invite.settings', - ) send_user_updated_mock = mocker.patch( 'src.notifications.tasks.send_user_updated_notification.delay', ) - settings_mock.PROJECT_CONF = {'BILLING': True} first_name = 'John' last_name = 'Wick' diff --git a/backend/src/accounts/tests/services/test_transfer.py b/backend/src/accounts/tests/services/test_transfer.py index 27f94e647..8f73a0bb8 100644 --- a/backend/src/accounts/tests/services/test_transfer.py +++ b/backend/src/accounts/tests/services/test_transfer.py @@ -315,13 +315,9 @@ def test_after_transfer_actions__premium__ok(mocker): increase_plan_users_mock = mocker.patch( 'src.payment.tasks.increase_plan_users.delay', ) - settings_mock = mocker.patch( - 'src.accounts.services.user_transfer.settings', - ) send_user_updated_mock = mocker.patch( 'src.notifications.tasks.send_user_updated_notification.delay', ) - settings_mock.PROJECT_CONF = {'BILLING': True} service = UserTransferService() service.user = user service.prev_user = prev_user @@ -384,82 +380,9 @@ def test_after_transfer_actions__unlimited__ok(mocker): increase_plan_users_mock = mocker.patch( 'src.payment.tasks.increase_plan_users.delay', ) - settings_mock = mocker.patch( - 'src.accounts.services.user_transfer.settings', - ) - send_user_updated_mock = mocker.patch( - 'src.notifications.tasks.send_user_updated_notification.delay', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} - service = UserTransferService() - service.user = user - service.prev_user = prev_user - - # act - service._after_transfer_actions() - - # assert - identify_mock.assert_called_once_with(service.user) - assert group_mock.call_count == 2 - group_mock.assert_has_calls( - [ - mocker.call(service.prev_user), - mocker.call(service.user), - ], - ) - users_transferred_mock.assert_called_once_with( - user=service.prev_user, - ) - increase_plan_users_mock.assert_not_called() - send_user_updated_mock.assert_called_once_with( - logging=user.account.log_api_requests, - account_id=user.account_id, - user_data={ - 'id': user.id, - 'first_name': user.first_name, - 'last_name': user.last_name, - 'email': user.email, - 'photo': user.photo, - 'phone': user.phone, - 'status': user.status, - 'is_admin': user.is_admin, - 'is_account_owner': user.is_account_owner, - 'manager_id': None, - 'subordinates_ids': [], - 'invite_id': None, - 'vacation': None, - }, - ) - - -@pytest.mark.parametrize('plan', BillingPlanType.PAYMENT_PLANS) -def test_after_transfer_actions__disable_billing__ok(mocker, plan): - # arrange - account = create_test_account( - plan=plan, - billing_sync=True, - ) - user = create_test_user(account=account, is_account_owner=True) - prev_user = create_test_user(email='prev@test.test') - users_transferred_mock = mocker.patch( - 'src.analysis.services.AnalyticService.users_transferred', - ) - identify_mock = mocker.patch( - 'src.accounts.services.user_transfer.UserTransferService.identify', - ) - group_mock = mocker.patch( - 'src.accounts.services.user_transfer.UserTransferService.group', - ) - increase_plan_users_mock = mocker.patch( - 'src.payment.tasks.increase_plan_users.delay', - ) - settings_mock = mocker.patch( - 'src.accounts.services.user_transfer.settings', - ) send_user_updated_mock = mocker.patch( 'src.notifications.tasks.send_user_updated_notification.delay', ) - settings_mock.PROJECT_CONF = {'BILLING': False} service = UserTransferService() service.user = user service.prev_user = prev_user @@ -539,10 +462,6 @@ def test_deactivate_prev_user__ok(mocker): deactivate_mock = mocker.patch( 'src.accounts.services.user.UserService.deactivate', ) - settings_mock = mocker.patch( - 'src.accounts.services.user_transfer.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} # act service._deactivate_prev_user() @@ -605,10 +524,6 @@ def test_deactivate_prev_user__cancel_subscription__ok(mocker): deactivate_mock = mocker.patch( 'src.accounts.services.user.UserService.deactivate', ) - settings_mock = mocker.patch( - 'src.accounts.services.user_transfer.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} # act service._deactivate_prev_user() @@ -675,10 +590,6 @@ def test_deactivate_prev_user__disable_billing__ok(plan, mocker): deactivate_mock = mocker.patch( 'src.accounts.services.user.UserService.deactivate', ) - settings_mock = mocker.patch( - 'src.accounts.services.user_transfer.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': False} # act service._deactivate_prev_user() diff --git a/backend/src/accounts/tests/views/tenants/test_create.py b/backend/src/accounts/tests/views/tenants/test_create.py index 0dd172a4f..e86507083 100644 --- a/backend/src/accounts/tests/views/tenants/test_create.py +++ b/backend/src/accounts/tests/views/tenants/test_create.py @@ -35,10 +35,6 @@ def test_create__premium_plan__increase_master_acc_subscription( ): # arrange - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} master_account = create_test_account( plan=BillingPlanType.PREMIUM, billing_sync=True, @@ -172,10 +168,6 @@ def test_create__premium_plan__billing_disabled__not_increase_master_acc_subs( ): # arrange - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} master_account = create_test_account( plan=BillingPlanType.PREMIUM, billing_sync=False, diff --git a/backend/src/accounts/tests/views/tenants/test_delete.py b/backend/src/accounts/tests/views/tenants/test_delete.py index abc60e02b..5c644ce17 100644 --- a/backend/src/accounts/tests/views/tenants/test_delete.py +++ b/backend/src/accounts/tests/views/tenants/test_delete.py @@ -56,10 +56,6 @@ def test_delete__premium_plan__ok( 'src.accounts.views.' 'tenants.increase_plan_users.delay', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -119,10 +115,6 @@ def test_delete__premium_plan__billing_disabled__ok( 'src.accounts.views.' 'tenants.increase_plan_users.delay', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -183,10 +175,6 @@ def test_delete__unlimited_plan__ok( 'src.accounts.views.' 'tenants.increase_plan_users.delay', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -253,10 +241,6 @@ def test_delete__unlimited_plan__billing_disabled__ok( 'src.accounts.views.' 'tenants.increase_plan_users.delay', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -320,10 +304,6 @@ def test_delete__fractionalcoo_plan__ok( 'src.accounts.views.' 'tenants.increase_plan_users.delay', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -387,10 +367,6 @@ def test_delete__free_plan__ok( 'src.accounts.views.' 'tenants.increase_plan_users.delay', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -444,10 +420,6 @@ def test_delete__another_account_tenant__permission_denied(mocker, api_client): account=another_tenant_account, email='tenant_owner@test.test', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -474,10 +446,6 @@ def test_delete__another_account_not_tenant__permission_denied( account=another_account, email='another_owner@test.test', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -497,10 +465,6 @@ def test_delete__tenant__permission_denied( lease_level=LeaseLevel.TENANT, ) master_account_owner = create_test_user(account=master_account) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -520,10 +484,6 @@ def test_delete__expired_subscription__permission_denied( plan_expiration=timezone.now() - datetime.timedelta(hours=1), ) master_account_owner = create_test_user(account=master_account) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -546,10 +506,6 @@ def test_delete__not_admin__permission_denied( is_admin=False, is_account_owner=False, ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_not_admin) # act @@ -569,10 +525,6 @@ def test_delete__not_authenticated__auth_error( lease_level=LeaseLevel.TENANT, ) create_test_user(account=master_account) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} # act response = api_client.delete('/tenants/123') @@ -623,10 +575,6 @@ def test_delete__stripe_exception__validation_error( 'src.accounts.views.' 'tenants.increase_plan_users.delay', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -645,68 +593,3 @@ def test_delete__stripe_exception__validation_error( account_service_init_mock.assert_not_called() update_users_counts_mock.assert_not_called() increase_plan_users_mock.assert_not_called() - - -@pytest.mark.parametrize('plan', BillingPlanType.PAYMENT_PLANS) -def test_delete__disable_billing__permission_denied( - plan, - mocker, - api_client, -): - # arrange - master_account = create_test_account(plan=plan) - master_account_owner = create_test_user(account=master_account) - tenant_account = create_test_account( - name='tenant', - tenant_name='old name', - plan=plan, - lease_level=LeaseLevel.TENANT, - master_account=master_account, - ) - create_test_user( - account=tenant_account, - email='tenant_owner@test.test', - ) - account_service_init_mock = mocker.patch.object( - AccountService, - attribute='__init__', - return_value=None, - ) - update_users_counts_mock = mocker.patch( - 'src.accounts.services.account.AccountService' - '.update_users_counts', - ) - stripe_service_init_mock = mocker.patch.object( - StripeService, - attribute='__init__', - return_value=None, - ) - cancel_subscription_mock = mocker.patch( - 'src.payment.stripe.service.StripeService.' - 'cancel_subscription', - ) - increase_plan_users_mock = mocker.patch( - 'src.accounts.views.' - 'tenants.increase_plan_users.delay', - ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': False} - api_client.token_authenticate(master_account_owner) - - # act - response = api_client.delete(f'/tenants/{tenant_account.id}') - - # assert - assert response.status_code == 204 - account_service_init_mock.assert_called_once_with( - is_superuser=False, - auth_type=AuthTokenType.USER, - instance=master_account, - user=master_account_owner, - ) - update_users_counts_mock.assert_called_once() - increase_plan_users_mock.assert_not_called() - stripe_service_init_mock.assert_not_called() - cancel_subscription_mock.assert_not_called() diff --git a/backend/src/accounts/tests/views/tenants/test_update.py b/backend/src/accounts/tests/views/tenants/test_update.py index fbe57182a..cb5f5eae3 100644 --- a/backend/src/accounts/tests/views/tenants/test_update.py +++ b/backend/src/accounts/tests/views/tenants/test_update.py @@ -54,10 +54,6 @@ def test_update__any_premium_plan__ok( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -119,10 +115,6 @@ def test_update__same_tenant_name__ok( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -159,10 +151,6 @@ def test_update__free_plan__permission_denied( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -189,10 +177,6 @@ def test_update_not_exists__permission_denied( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -230,10 +214,6 @@ def test_update__another_account_tenant__permission_denied( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -271,10 +251,6 @@ def test_update__another_account_not_tenant__permission_denied( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -320,10 +296,6 @@ def test_update__stripe_exception__validation_error( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -370,10 +342,6 @@ def test_update__blank_tenant_name__validation_error( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -419,10 +387,6 @@ def test_update__null_tenant_name__validation_error( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -474,10 +438,7 @@ def test_update__skip_tenant_name__not_change( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} + api_client.token_authenticate(master_account_owner) # act @@ -511,10 +472,6 @@ def test_update__tenant__permission_denied( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -545,10 +502,6 @@ def test_update__expired_subscription__permission_denied( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_owner) # act @@ -583,10 +536,6 @@ def test_update__not_admin__permission_denied( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} api_client.token_authenticate(master_account_not_admin) # act @@ -618,10 +567,6 @@ def test_update__not_authenticated__auth_error( 'src.payment.stripe.service.StripeService.' 'update_subscription_description', ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} # act response = api_client.patch( @@ -634,60 +579,3 @@ def test_update__not_authenticated__auth_error( # assert assert response.status_code == 401 update_subscription_description_mock.assert_not_called() - - -@pytest.mark.parametrize('plan', BillingPlanType.PAYMENT_PLANS) -def test_update__disable_billing__ok( - plan, - mocker, - api_client, -): - # arrange - master_account = create_test_account( - plan=plan, - plan_expiration=timezone.now() + timedelta(days=1), - ) - master_account_owner = create_test_user(account=master_account) - tenant_name = 'some name' - tenant_account = create_test_account( - name='tenant', - tenant_name='old name', - plan=plan, - plan_expiration=timezone.now() + timedelta(days=1), - lease_level=LeaseLevel.TENANT, - master_account=master_account, - ) - create_test_user( - account=tenant_account, - email='tenant_owner@test.test', - ) - stripe_service_init_mock = mocker.patch.object( - StripeService, - attribute='__init__', - return_value=None, - ) - update_subscription_description_mock = mocker.patch( - 'src.payment.stripe.service.StripeService.' - 'update_subscription_description', - ) - settings_mock = mocker.patch( - 'src.accounts.views.tenants.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': False} - api_client.token_authenticate(master_account_owner) - - # act - response = api_client.patch( - f'/tenants/{tenant_account.id}', - data={ - 'tenant_name': tenant_name, - }, - ) - - # assert - assert response.status_code == 200 - assert response.data['id'] == tenant_account.id - assert response.data['tenant_name'] == tenant_name - assert response.data['date_joined'] - stripe_service_init_mock.assert_not_called() - update_subscription_description_mock.assert_not_called() diff --git a/backend/src/accounts/views/tenants.py b/backend/src/accounts/views/tenants.py index ecbf1d9c2..d863ec056 100644 --- a/backend/src/accounts/views/tenants.py +++ b/backend/src/accounts/views/tenants.py @@ -1,4 +1,3 @@ -from django.conf import settings from django.contrib.auth import get_user_model from django.db import transaction from rest_framework.decorators import action @@ -90,9 +89,7 @@ def get_queryset(self): def perform_destroy(self, instance: Account): master_account = self.request.user.account - billing_enabled = ( - instance.billing_sync and settings.PROJECT_CONF['BILLING'] - ) + billing_enabled = instance.billing_sync with transaction.atomic(): if ( instance.billing_plan == BillingPlanType.UNLIMITED @@ -142,7 +139,6 @@ def patch(self, request, *args, **kwargs): new_tenant_name is not None and new_tenant_name != old_tenant_name and instance.billing_sync - and settings.PROJECT_CONF['BILLING'] ): try: stripe_service = StripeService( @@ -186,10 +182,7 @@ def create(self, request, **kwargs): service = SystemWorkflowService(user=tenant_user) service.create_onboarding_templates() service.create_activated_templates() - billing_enabled = ( - settings.PROJECT_CONF['BILLING'] - and master_account.billing_sync - ) + billing_enabled = master_account.billing_sync if ( tenant_account.billing_plan == BillingPlanType.PREMIUM and billing_enabled diff --git a/backend/src/authentication/tests/test_services/test_auth0_service.py b/backend/src/authentication/tests/test_services/test_auth0_service.py index dd6aefce8..09f1de8be 100644 --- a/backend/src/authentication/tests/test_services/test_auth0_service.py +++ b/backend/src/authentication/tests/test_services/test_auth0_service.py @@ -925,7 +925,6 @@ def test_authenticate_user__invited_user_activated__ok(mocker): settings_mock.PROJECT_CONF = { 'SSO_AUTH': True, 'SSO_PROVIDER': 'auth0', - 'BILLING': False, } settings_mock.AUTH0_CLIENT_SECRET = 'test_secret' service = Auth0Service() @@ -1041,7 +1040,6 @@ def test_authenticate_user__inactive_user_creates_new__ok(mocker): settings_mock.PROJECT_CONF = { 'SSO_AUTH': True, 'SSO_PROVIDER': 'auth0', - 'BILLING': False, } settings_mock.AUTH0_CLIENT_SECRET = 'test_secret' service = Auth0Service() diff --git a/backend/src/authentication/tests/test_services/test_okta_service.py b/backend/src/authentication/tests/test_services/test_okta_service.py index a314d9077..e521bd798 100644 --- a/backend/src/authentication/tests/test_services/test_okta_service.py +++ b/backend/src/authentication/tests/test_services/test_okta_service.py @@ -1208,7 +1208,6 @@ def test_authenticate_user__invited_user_activated__ok(mocker): settings_mock.PROJECT_CONF = { 'SSO_AUTH': True, 'SSO_PROVIDER': 'okta', - 'BILLING': False, } settings_mock.OKTA_CLIENT_SECRET = 'test_secret' service = OktaService() @@ -1323,7 +1322,6 @@ def test_authenticate_user__inactive_user_creates_new__ok(mocker): settings_mock.PROJECT_CONF = { 'SSO_AUTH': True, 'SSO_PROVIDER': 'okta', - 'BILLING': False, } settings_mock.OKTA_CLIENT_SECRET = 'test_secret' service = OktaService() diff --git a/backend/src/authentication/tests/test_views/test_mixins.py b/backend/src/authentication/tests/test_views/test_mixins.py index 9765564bc..1e6413f05 100644 --- a/backend/src/authentication/tests/test_views/test_mixins.py +++ b/backend/src/authentication/tests/test_views/test_mixins.py @@ -82,10 +82,6 @@ def test_create__all_fields__ok( 'src.accounts.services.user.UserService.create', return_value=user, ) - settings_mock = mocker.patch( - 'src.authentication.views.mixins.settings', - ) - settings_mock.PROJECT_CONF = {'BILLING': True} after_signup_mock = mocker.patch( 'src.authentication.views.mixins.SignUpMixin.' 'after_signup', @@ -140,6 +136,7 @@ def test_create__all_fields__ok( utm_campaign=utm_campaign, utm_term=utm_term, utm_content=utm_content, + billing_sync=True, gclid=gclid, ) @@ -255,7 +252,6 @@ def test_create__account_service_exception__validation_error( ) settings_mock.SLACK = True settings_mock.SLACK_CONFIG = {'NOTIFY_ON_SIGNUP': False} - settings_mock.PROJECT_CONF = {'BILLING': True} notification_mock = mocker.patch( 'src.authentication.tasks.' 'send_new_signup_notification.delay', @@ -300,7 +296,7 @@ def test_create__account_service_exception__validation_error( utm_term=None, utm_content=None, gclid=None, - billing_sync=True, + billing_sync=False, ) user_create_mock.assert_not_called() stripe_service_init_mock.assert_not_called() @@ -378,7 +374,6 @@ def test_create__user_service_exception__validation_error( ) settings_mock.SLACK = True settings_mock.SLACK_CONFIG = {'NOTIFY_ON_SIGNUP': True} - settings_mock.PROJECT_CONF = {'BILLING': True} notification_mock = mocker.patch( 'src.authentication.tasks.' 'send_new_signup_notification.delay', @@ -423,7 +418,7 @@ def test_create__user_service_exception__validation_error( utm_term=None, utm_content=None, gclid=None, - billing_sync=True, + billing_sync=False, ) user_create_mock.assert_called_once_with( account=user.account, @@ -520,7 +515,6 @@ def test_create__stripe_service_exception__skip_sync( ) settings_mock.SLACK = True settings_mock.SLACK_CONFIG = {'NOTIFY_ON_SIGNUP': True} - settings_mock.PROJECT_CONF = {'BILLING': True} after_signup_mock = mocker.patch( 'src.authentication.views.mixins.SignUpMixin.' @@ -574,6 +568,7 @@ def test_create__stripe_service_exception__skip_sync( utm_campaign=utm_campaign, utm_term=utm_term, utm_content=utm_content, + billing_sync=True, gclid=gclid, ) @@ -633,145 +628,3 @@ def test_create__stripe_service_exception__skip_sync( user_agent=user_agent, user_ip=ip, ) - - -def test_create__disable_billing__skip_stripe_call( - api_client, - mocker, -): - # arrange - token = 'token' - authenticate_mock = mocker.patch( - 'src.authentication.views.mixins.' - 'AuthService.get_auth_token', - return_value=token, - ) - stripe_service_init_mock = mocker.patch.object( - StripeService, - attribute='__init__', - return_value=None, - ) - update_customer_mock = mocker.patch( - 'src.payment.stripe.service.' - 'StripeService.update_customer', - ) - sys_workflow_service_init_mock = mocker.patch.object( - SystemWorkflowService, - attribute='__init__', - return_value=None, - ) - create_onboarding_templates_mock = mocker.patch( - 'src.processes.services.system_workflows.' - 'SystemWorkflowService.create_onboarding_templates', - ) - create_onboarding_workflows_mock = mocker.patch( - 'src.processes.services.system_workflows.' - 'SystemWorkflowService.create_onboarding_workflows', - ) - create_activated_templates_mock = mocker.patch( - 'src.processes.services.system_workflows.' - 'SystemWorkflowService.create_activated_templates', - ) - create_activated_workflows_mock = mocker.patch( - 'src.processes.services.system_workflows.' - 'SystemWorkflowService.create_activated_workflows', - ) - account_service_init_mock = mocker.patch.object( - AccountService, - attribute='__init__', - return_value=None, - ) - user_service_init_mock = mocker.patch.object( - UserService, - attribute='__init__', - return_value=None, - ) - user = create_test_user(is_account_owner=True) - account_create_mock = mocker.patch( - 'src.accounts.services.account.AccountService.create', - return_value=user.account, - ) - user_create_mock = mocker.patch( - 'src.accounts.services.user.UserService.create', - return_value=user, - ) - settings_mock = mocker.patch( - 'src.authentication.views.mixins.settings', - ) - settings_mock.SLACK = True - settings_mock.SLACK_CONFIG = {'NOTIFY_ON_SIGNUP': True} - settings_mock.PROJECT_CONF = {'BILLING': False} - - after_signup_mock = mocker.patch( - 'src.authentication.views.mixins.SignUpMixin.' - 'after_signup', - ) - - email = 'Test@pneumatiC.App' - is_superuser = False - user_agent = 'some agent' - ip = '456' - request_mock = mocker.Mock( - is_superuser=is_superuser, - headers={ - 'User-Agent': user_agent, - }, - META={ - 'HTTP_X_REAL_IP': ip, - }, - ) - - view = SignUpMixin() - view.request = request_mock - - # act - result = view.signup( - email=email, - ) - - # assert - assert result[0] == user - assert result[1] == token - account_service_init_mock.assert_called_once_with( - is_superuser=is_superuser, - auth_type=AuthTokenType.USER, - ) - user_service_init_mock.assert_called_once_with( - is_superuser=is_superuser, - auth_type=AuthTokenType.USER, - ) - account_create_mock.assert_called_once_with( - name=None, - utm_source=None, - utm_medium=None, - utm_campaign=None, - utm_term=None, - utm_content=None, - gclid=None, - billing_sync=True, - ) - user_create_mock.assert_called_once_with( - account=user.account, - phone=None, - email=email, - first_name=None, - last_name=None, - photo=None, - raw_password=None, - is_account_owner=True, - language=None, - timezone=None, - ) - stripe_service_init_mock.assert_not_called() - update_customer_mock.assert_not_called() - sys_workflow_service_init_mock.assert_called_once_with(user=user) - create_onboarding_templates_mock.assert_called_once() - create_onboarding_workflows_mock.assert_called_once() - create_activated_templates_mock.assert_called_once() - create_activated_workflows_mock.assert_called_once() - after_signup_mock.assert_called_once_with(user) - authenticate_mock.assert_called_once_with( - user=user, - user_agent=user_agent, - user_ip=ip, - ) diff --git a/backend/src/authentication/views/mixins.py b/backend/src/authentication/views/mixins.py index 743ee1327..ea602bb43 100644 --- a/backend/src/authentication/views/mixins.py +++ b/backend/src/authentication/views/mixins.py @@ -109,7 +109,7 @@ def signup( utm_term: Optional[str] = None, utm_content: Optional[str] = None, gclid: Optional[str] = None, - billing_sync: bool = True, + billing_sync: bool = settings.PROJECT_CONF['BILLING'], request: Optional[HttpRequest] = None, ms_graph_user_id: Optional[str] = None, ) -> Tuple[UserModel, PneumaticToken]: @@ -151,7 +151,7 @@ def signup( except (AccountServiceException, UserServiceException) as ex: raise_validation_error(message=ex.message) else: - if settings.PROJECT_CONF['BILLING'] and billing_sync: + if billing_sync: try: stripe_service = StripeService(user=account_owner) stripe_service.update_customer() diff --git a/backend/src/generics/throttling.py b/backend/src/generics/throttling.py index 5062b4a18..0048d7f7d 100644 --- a/backend/src/generics/throttling.py +++ b/backend/src/generics/throttling.py @@ -115,7 +115,7 @@ def skip_condition(self, request) -> bool: user = request.user if not user.is_authenticated: return True - return bool(self.skip_for_paid_accounts and user.account.is_paid) + return self.skip_for_paid_accounts class TokenThrottle(BaseAuthThrottle): diff --git a/backend/src/payment/permissions.py b/backend/src/payment/permissions.py deleted file mode 100644 index c5d68d88d..000000000 --- a/backend/src/payment/permissions.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.conf import settings -from rest_framework.permissions import BasePermission - -from src.payment.messages import MSG_BL_0021 - - -class ProjectBillingPermission(BasePermission): - - message = MSG_BL_0021 - - def has_permission(self, request, view): - return settings.PROJECT_CONF['BILLING'] diff --git a/backend/src/payment/stripe/service.py b/backend/src/payment/stripe/service.py index 1e83ae71b..dcd743d11 100644 --- a/backend/src/payment/stripe/service.py +++ b/backend/src/payment/stripe/service.py @@ -115,7 +115,11 @@ def _get_current_subscription(self) -> Optional[stripe.Subscription]: customer=self.customer, subscription_account=self.subscription_account, ) - if self.account.billing_sync: + if ( + self.account.billing_sync + and self.subscription_account.billing_plan + in BillingPlanType.PAYMENT_PLANS + ): if subscription and not self.subscription_account.is_subscribed: self.subscription_service.create( details=self.get_subscription_details(subscription), diff --git a/backend/src/payment/tests/test_views/test_cancel.py b/backend/src/payment/tests/test_views/test_cancel.py index eecf258bd..d0fad2a4f 100644 --- a/backend/src/payment/tests/test_views/test_cancel.py +++ b/backend/src/payment/tests/test_views/test_cancel.py @@ -2,7 +2,6 @@ from django.contrib.auth import get_user_model from src.authentication.enums import AuthTokenType -from src.payment import messages from src.payment.stripe.exceptions import ( StripeServiceException, ) @@ -27,11 +26,6 @@ def test_cancel_subscription__ok( attribute='__init__', return_value=None, ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) cancel_subscription_mock = mocker.patch( 'src.payment.stripe.' 'service.StripeService.cancel_subscription', @@ -63,11 +57,6 @@ def test_cancel_service_exception__validation_error( return_value=None, ) message = 'some message' - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) cancel_subscription_mock = mocker.patch( 'src.payment.stripe.' 'service.StripeService.cancel_subscription', @@ -88,35 +77,3 @@ def test_cancel_service_exception__validation_error( is_superuser=False, ) cancel_subscription_mock.assert_called_once() - - -def test_cancel_subscription__disable_billing__permission_denied( - mocker, - api_client, -): - # arrange - user = create_test_user() - service_init_mock = mocker.patch.object( - StripeService, - attribute='__init__', - return_value=None, - ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=False, - ) - cancel_subscription_mock = mocker.patch( - 'src.payment.stripe.' - 'service.StripeService.cancel_subscription', - ) - api_client.token_authenticate(user) - - # act - response = api_client.post('/payment/subscription/cancel') - - # assert - assert response.status_code == 403 - assert response.data['detail'] == messages.MSG_BL_0021 - service_init_mock.assert_not_called() - cancel_subscription_mock.assert_not_called() diff --git a/backend/src/payment/tests/test_views/test_card_setup.py b/backend/src/payment/tests/test_views/test_card_setup.py index 283ef1c68..408eef94f 100644 --- a/backend/src/payment/tests/test_views/test_card_setup.py +++ b/backend/src/payment/tests/test_views/test_card_setup.py @@ -2,7 +2,6 @@ from django.contrib.auth import get_user_model from src.authentication.enums import AuthTokenType -from src.payment import messages from src.payment.stripe.exceptions import ( StripeServiceException, ) @@ -36,11 +35,6 @@ def test_card_setup__payment_link__ok( 'get_payment_method_checkout_link', return_value=setup_link, ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -87,11 +81,6 @@ def test_card_setup__service_exception__validation_error( 'get_payment_method_checkout_link', side_effect=StripeServiceException(message), ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -136,11 +125,6 @@ def test_card_setup__success_url_is_skipped__validation_error( 'src.payment.stripe.service.StripeService.' 'get_payment_method_checkout_link', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -180,11 +164,6 @@ def test_card_setup__success_url_invalid__validation_error( 'src.payment.stripe.service.StripeService.' 'get_payment_method_checkout_link', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -225,11 +204,6 @@ def test_card_setup__cancel_url_invalid__validation_error( 'src.payment.stripe.service.StripeService.' 'get_payment_method_checkout_link', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) # act @@ -250,47 +224,3 @@ def test_card_setup__cancel_url_invalid__validation_error( assert response.data['details']['name'] == 'cancel_url' service_init_mock.assert_not_called() card_setup_mock.assert_not_called() - - -def test_card_setup__disable_billing__permission_denied( - mocker, - api_client, -): - # arrange - user = create_test_user() - success_url = 'http://localhost/success/' - cancel_url = 'http://localhost/cancel/' - setup_link = 'checkout.stripe.com' - - service_init_mock = mocker.patch.object( - StripeService, - attribute='__init__', - return_value=None, - ) - card_setup_mock = mocker.patch( - 'src.payment.stripe.service.StripeService.' - 'get_payment_method_checkout_link', - return_value=setup_link, - ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=False, - ) - - api_client.token_authenticate(user) - - # act - response = api_client.get( - '/payment/card-setup', - data={ - 'success_url': success_url, - 'cancel_url': cancel_url, - }, - ) - - # assert - assert response.status_code == 403 - assert response.data['detail'] == messages.MSG_BL_0021 - service_init_mock.assert_not_called() - card_setup_mock.assert_not_called() diff --git a/backend/src/payment/tests/test_views/test_confirm.py b/backend/src/payment/tests/test_views/test_confirm.py index 739ad26e2..c4fe29944 100644 --- a/backend/src/payment/tests/test_views/test_confirm.py +++ b/backend/src/payment/tests/test_views/test_confirm.py @@ -37,11 +37,6 @@ def test_confirm__ok( confirm_mock = mocker.patch( 'src.payment.stripe.service.StripeService.confirm', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -89,11 +84,6 @@ def test_confirm__subscription_data__ok( confirm_mock = mocker.patch( 'src.payment.stripe.service.StripeService.confirm', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -132,11 +122,6 @@ def test_confirm__skip_token__validation_error( confirm_mock = mocker.patch( 'src.payment.stripe.service.StripeService.confirm', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -175,11 +160,6 @@ def test_confirm__invalid_token__validation_error( confirm_mock = mocker.patch( 'src.payment.stripe.service.StripeService.confirm', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) invalid_token = '!@#ASEwadd13' api_client.token_authenticate(user) @@ -200,47 +180,3 @@ def test_confirm__invalid_token__validation_error( get_token_mock.assert_called_once_with(invalid_token) service_init_mock.assert_not_called() confirm_mock.assert_not_called() - - -def test_confirm__disable_billing__permission_denied( - mocker, - api_client, -): - # arrange - account = create_test_account() - user = create_test_user(account=account) - token = ConfirmToken() - token['user_id'] = user.id - token['account_id'] = user.account.id - token['is_superuser'] = False - token['auth_type'] = AuthTokenType.API - - service_init_mock = mocker.patch.object( - StripeService, - attribute='__init__', - return_value=None, - ) - confirm_mock = mocker.patch( - 'src.payment.stripe.service.StripeService.confirm', - ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=False, - ) - - api_client.token_authenticate(user) - - # act - response = api_client.get( - '/payment/confirm', - data={ - 'token': str(token), - }, - ) - - # assert - assert response.status_code == 403 - service_init_mock.assert_not_called() - confirm_mock.assert_not_called() - assert response.data['detail'] == messages.MSG_BL_0021 diff --git a/backend/src/payment/tests/test_views/test_customer_portal.py b/backend/src/payment/tests/test_views/test_customer_portal.py index 9a8600542..27e944dc1 100644 --- a/backend/src/payment/tests/test_views/test_customer_portal.py +++ b/backend/src/payment/tests/test_views/test_customer_portal.py @@ -2,7 +2,6 @@ from django.contrib.auth import get_user_model from src.authentication.enums import AuthTokenType -from src.payment import messages from src.payment.stripe.exceptions import ( StripeServiceException, ) @@ -35,11 +34,6 @@ def test_get_customer_portal_link__ok( 'get_customer_portal_link', return_value=customer_portal_link, ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -83,11 +77,6 @@ def test_get_customer_portal_link__service_exception__validation_error( 'get_customer_portal_link', side_effect=StripeServiceException(message), ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -130,11 +119,6 @@ def test_get_customer_portal_link__invalid_cancel_url__validation_error( 'src.payment.stripe.service.StripeService.' 'get_customer_portal_link', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -173,11 +157,6 @@ def test_get_customer_portal_link__skip_cancel_url__validation_error( 'src.payment.stripe.service.StripeService.' 'get_customer_portal_link', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) # act @@ -211,11 +190,6 @@ def test_get_customer_portal_link__cancel_url_is_null__validation_error( 'src.payment.stripe.service.StripeService.' 'get_customer_portal_link', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) # act @@ -258,53 +232,6 @@ def test_get_customer_portal_link__not_account_owner__permission_denied( 'get_customer_portal_link', return_value=customer_portal_link, ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) - - api_client.token_authenticate(user) - - # act - response = api_client.get( - '/payment/customer-portal', - data={ - 'cancel_url': cancel_url, - }, - ) - - # assert - assert response.status_code == 403 - service_init_mock.assert_not_called() - get_customer_portal_link_mock.assert_not_called() - - -def test__disable_billing__permission_denied( - mocker, - api_client, -): - - # arrange - user = create_test_user(is_account_owner=True) - cancel_url = 'http://localhost/cancel/' - customer_portal_link = 'checkout.stripe.com/portal?token=123wsd' - - service_init_mock = mocker.patch.object( - StripeService, - attribute='__init__', - return_value=None, - ) - get_customer_portal_link_mock = mocker.patch( - 'src.payment.stripe.service.StripeService.' - 'get_customer_portal_link', - return_value=customer_portal_link, - ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=False, - ) api_client.token_authenticate(user) @@ -318,6 +245,5 @@ def test__disable_billing__permission_denied( # assert assert response.status_code == 403 - assert response.data['detail'] == messages.MSG_BL_0021 service_init_mock.assert_not_called() get_customer_portal_link_mock.assert_not_called() diff --git a/backend/src/payment/tests/test_views/test_default_payment_method.py b/backend/src/payment/tests/test_views/test_default_payment_method.py index f87db264c..c8fa46649 100644 --- a/backend/src/payment/tests/test_views/test_default_payment_method.py +++ b/backend/src/payment/tests/test_views/test_default_payment_method.py @@ -2,7 +2,6 @@ from django.contrib.auth import get_user_model from src.authentication.enums import AuthTokenType -from src.payment import messages from src.payment.stripe.entities import CardDetails from src.payment.stripe.service import StripeService from src.processes.tests.fixtures import ( @@ -33,11 +32,6 @@ def test_default_payment_method__ok( '.get_payment_method', return_value=CardDetails(last4=last4, brand=brand), ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -73,11 +67,6 @@ def test_default_payment_method__not_exist__not_found( '.get_payment_method', return_value=None, ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -92,40 +81,3 @@ def test_default_payment_method__not_exist__not_found( is_superuser=False, ) get_payment_method_mock.assert_called_once() - - -def test_default_payment_method__disable_billing__permission_denied( - api_client, - mocker, -): - # arrange - account = create_test_account() - user = create_test_user(account=account) - last4 = '1234' - brand = 'Maestro' - service_init_mock = mocker.patch.object( - StripeService, - attribute='__init__', - return_value=None, - ) - get_payment_method_mock = mocker.patch( - 'src.payment.stripe.service.StripeService' - '.get_payment_method', - return_value=CardDetails(last4=last4, brand=brand), - ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=False, - ) - - api_client.token_authenticate(user) - - # act - response = api_client.get('/payment/default-payment-method') - - # assert - assert response.status_code == 403 - assert response.data['detail'] == messages.MSG_BL_0021 - service_init_mock.assert_not_called() - get_payment_method_mock.assert_not_called() diff --git a/backend/src/payment/tests/test_views/test_products.py b/backend/src/payment/tests/test_views/test_products.py index d6e9a29ac..5655c9681 100644 --- a/backend/src/payment/tests/test_views/test_products.py +++ b/backend/src/payment/tests/test_views/test_products.py @@ -1,7 +1,6 @@ import pytest from django.contrib.auth import get_user_model -from src.payment import messages from src.payment.enums import PriceStatus from src.payment.tests.fixtures import ( create_test_invoice_price, @@ -61,11 +60,6 @@ def test_products__ok( ) create_test_product(is_active=False) api_client.token_authenticate(user) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) # act response = api_client.get('/payment/products') @@ -124,11 +118,6 @@ def test_products__archived_price__ok( max_quantity=20, ) api_client.token_authenticate(user) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) # act response = api_client.get('/payment/products') @@ -151,41 +140,3 @@ def test_products__archived_price__ok( assert price_1_data['price'] == price_1.price assert price_1_data['trial_days'] == price_1.trial_days assert price_1_data['billing_period'] == price_1.billing_period - - -def test_products__disable_billing__permission_denied( - mocker, - api_client, -): - # arrange - account = create_test_account() - user = create_test_user(account=account) - product = create_test_product( - stripe_id='prod_1', - code='some code', - name='Prem', - is_active=True, - is_subscription=True, - ) - create_test_recurring_price( - product=product, - status=PriceStatus.ACTIVE, - trial_days=1, - code='prem_month', - stripe_id='price_1', - min_quantity=5, - max_quantity=1000, - ) - api_client.token_authenticate(user) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=False, - ) - - # act - response = api_client.get('/payment/products') - - # assert - assert response.status_code == 403 - assert response.data['detail'] == messages.MSG_BL_0021 diff --git a/backend/src/payment/tests/test_views/test_purchase.py b/backend/src/payment/tests/test_views/test_purchase.py index ce5e4ceb6..416052fa9 100644 --- a/backend/src/payment/tests/test_views/test_purchase.py +++ b/backend/src/payment/tests/test_views/test_purchase.py @@ -45,11 +45,6 @@ def test_purchase__payment_link__ok( 'service.StripeService.create_purchase', return_value=payment_link, ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -110,11 +105,6 @@ def test_purchase__off_session__ok( 'StripeService.create_purchase', return_value=None, ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -176,11 +166,6 @@ def test_purchase__archived_price__ok( 'service.StripeService.create_purchase', return_value=payment_link, ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -225,11 +210,6 @@ def test_purchase__service_exception__validation_error( 'service.StripeService.create_purchase', side_effect=StripeServiceException(message), ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -285,11 +265,6 @@ def test_purchase__empty_products__validation_error( 'src.payment.stripe.' 'service.StripeService.create_purchase', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -328,11 +303,6 @@ def test_purchase__null_products__validation_error( 'src.payment.stripe.' 'service.StripeService.create_purchase', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -372,11 +342,6 @@ def test_purchase__quantity_less_then_1__validation_error( 'src.payment.stripe.' 'service.StripeService.create_purchase', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -420,11 +385,6 @@ def test_purchase__success_url_is_skipped__validation_error( 'src.payment.stripe.' 'service.StripeService.create_purchase', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -467,11 +427,6 @@ def test_purchase__success_url_invalid__validation_error( 'src.payment.stripe.' 'service.StripeService.create_purchase', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -515,11 +470,6 @@ def test_purchase__cancel_url_invalid__validation_error( 'src.payment.stripe.' 'service.StripeService.create_purchase', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) # act @@ -580,11 +530,6 @@ def test_purchase__not_existent_product__validation_error( 'src.payment.stripe.' 'service.StripeService.create_purchase', ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -640,11 +585,6 @@ def test_purchase__not_existent_products__validation_error( code=price_code_3, status=PriceStatus.ACTIVE, ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) api_client.token_authenticate(user) @@ -680,55 +620,3 @@ def test_purchase__not_existent_products__validation_error( assert (response.data['message'] == message) or ( response.data['message'] == message_reversed ) - - -def test_purchase__disable_billing__permission_denied( - mocker, - api_client, -): - # arrange - user = create_test_user() - success_url = 'http://localhost/success/' - cancel_url = 'http://localhost/cancel/' - price = create_test_recurring_price() - quantity = 1 - payment_link = 'checkout.stripe.com' - - service_init_mock = mocker.patch.object( - StripeService, - attribute='__init__', - return_value=None, - ) - create_purchase_mock = mocker.patch( - 'src.payment.stripe.' - 'service.StripeService.create_purchase', - return_value=payment_link, - ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=False, - ) - - api_client.token_authenticate(user) - - # act - response = api_client.post( - '/payment/purchase', - data={ - 'success_url': success_url, - 'cancel_url': cancel_url, - 'products': [ - { - 'code': price.code, - 'quantity': quantity, - }, - ], - }, - ) - - # assert - assert response.status_code == 403 - assert response.data['detail'] == messages.MSG_BL_0021 - service_init_mock.assert_not_called() - create_purchase_mock.assert_not_called() diff --git a/backend/src/payment/tests/test_views/test_webhooks.py b/backend/src/payment/tests/test_views/test_webhooks.py index a317d3867..b7ac4ae92 100644 --- a/backend/src/payment/tests/test_views/test_webhooks.py +++ b/backend/src/payment/tests/test_views/test_webhooks.py @@ -21,11 +21,6 @@ def test_webhook__ok(api_client, mocker): '.has_permission', return_value=True, ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=True, - ) # act response = api_client.post( @@ -39,42 +34,3 @@ def test_webhook__ok(api_client, mocker): task_mock.assert_called_once_with( data=data, ) - - -def test_webhook__disable_billing__permission_denied(api_client, mocker): - - # arrange - data = { - "id": "evt_2Zj5zzFU3a9abcZ1aYYYaaZ1", - "type": "some type", - "object": "event", - "api_version": "2022-11-15", - "created": 1633887337, - "data": { - "object": {}, - }, - } - task_mock = mocker.patch( - 'src.payment.views.handle_webhook.delay', - ) - has_permission_mock = mocker.patch( - 'src.payment.views.StripeWebhookPermission' - '.has_permission', - return_value=True, - ) - mocker.patch( - 'src.payment.views.ProjectBillingPermission' - '.has_permission', - return_value=False, - ) - - # act - response = api_client.post( - path='/payment/stripe/webhooks', - data=data, - ) - - # assert - assert response.status_code == 401 - has_permission_mock.assert_not_called() - task_mock.assert_not_called() diff --git a/backend/src/payment/views.py b/backend/src/payment/views.py index 5e91ad9fb..9ef1f58c1 100644 --- a/backend/src/payment/views.py +++ b/backend/src/payment/views.py @@ -16,9 +16,6 @@ Price, Product, ) -from src.payment.permissions import ( - ProjectBillingPermission, -) from src.payment.serializers import ( CardSetupSerializer, ConfirmSerializer, @@ -55,7 +52,7 @@ class PaymentViewSet( def get_permissions(self): if self.action == 'confirm': - return (ProjectBillingPermission(),) + return () if self.action in { 'purchase', 'card_setup', @@ -63,13 +60,11 @@ def get_permissions(self): 'customer_portal', }: return ( - ProjectBillingPermission(), UserIsAuthenticated(), AccountOwnerPermission(), DisallowForTenantPermission(), ) return ( - ProjectBillingPermission(), UserIsAuthenticated(), UserIsAdminOrAccountOwner(), DisallowForTenantPermission(), @@ -188,7 +183,6 @@ class SubscriptionViewSet( ): permission_classes = ( - ProjectBillingPermission, UserIsAuthenticated, AccountOwnerPermission, DisallowForTenantPermission, @@ -218,7 +212,6 @@ class StripeViewSet( action_permission_classes = { 'webhooks': ( - ProjectBillingPermission(), StripeWebhookPermission(), ), } diff --git a/backend/src/settings.py b/backend/src/settings.py index 7ef012d71..4de3e4ba9 100644 --- a/backend/src/settings.py +++ b/backend/src/settings.py @@ -335,7 +335,7 @@ class Common(Configuration): else: STRIPE_WEBHOOK_IP_WHITELIST = [] - DEFAULT_MAX_USERS = 5 + DEFAULT_MAX_USERS = 1000 # Account verification VERIFICATION_CHECK = env.get('VERIFICATION_CHECK') == 'yes' @@ -473,6 +473,11 @@ class Common(Configuration): }, } + # Django Guardian - using built-in models + # Disable anonymous user creation (not needed for this project) + ANONYMOUS_USER_NAME = None + ANONYMOUS_USER_ID = -1 + class Testing(Common): @@ -566,10 +571,6 @@ class Development(Common): }, } - # Django Guardian - using built-in models - # Disable anonymous user creation (not needed for this project) - ANONYMOUS_USER_NAME = None - ANONYMOUS_USER_ID = -1 class Staging(Development): @@ -598,4 +599,4 @@ class Staging(Development): class Production(Staging): - MAX_INVITES = 100 + MAX_INVITES = 1000