diff --git a/database/models/core.py b/database/models/core.py index 9ca77ca0b..a52ed804c 100644 --- a/database/models/core.py +++ b/database/models/core.py @@ -5,7 +5,7 @@ from functools import cached_property from typing import Optional -from shared.plan.constants import PlanName +from shared.plan.constants import DEFAULT_FREE_PLAN from sqlalchemy import Column, ForeignKey, Index, UniqueConstraint, types from sqlalchemy.dialects import postgresql from sqlalchemy.orm import Session, backref, relationship, validates @@ -62,7 +62,7 @@ class Account(CodecovBaseModel, MixinBaseClassNoExternalID): plan = Column( types.String(50), nullable=False, - default=PlanName.BASIC_PLAN_NAME.value, # TODO: UPDATE WITH NEW FREE PLAN NAME + default=DEFAULT_FREE_PLAN, ) plan_seat_count = Column(types.SmallInteger, nullable=False, default=1) free_seat_count = Column(types.SmallInteger, nullable=False, default=0) diff --git a/database/tests/factories/core.py b/database/tests/factories/core.py index 1efefc28e..a3f5b9ddd 100644 --- a/database/tests/factories/core.py +++ b/database/tests/factories/core.py @@ -5,7 +5,7 @@ import factory from factory import Factory from shared.django_apps.codecov_auth.models import Plan, Tier -from shared.plan.constants import PlanName, TierName +from shared.plan.constants import DEFAULT_FREE_PLAN, TierName from database import enums, models from services.encryption import encryptor @@ -51,7 +51,7 @@ class Meta: trial_status = enums.TrialStatus.NOT_STARTED.value trial_fired_by = None upload_token_required_for_public_repos = False - plan = PlanName.BASIC_PLAN_NAME.value + plan = DEFAULT_FREE_PLAN oauth_token = factory.LazyAttribute( lambda o: encrypt_oauth_token(o.unencrypted_oauth_token) @@ -325,7 +325,7 @@ class Meta: marketing_name = factory.Faker("catch_phrase") max_seats = 1 monthly_uploads_limit = None - name = PlanName.BASIC_PLAN_NAME.value + name = DEFAULT_FREE_PLAN paid_plan = False stripe_id = None diff --git a/database/tests/unit/test_models.py b/database/tests/unit/test_models.py index ce2bea1f3..4f8825cf9 100644 --- a/database/tests/unit/test_models.py +++ b/database/tests/unit/test_models.py @@ -2,7 +2,7 @@ from unittest.mock import PropertyMock, call from mock import MagicMock, patch -from shared.plan.constants import PlanName +from shared.plan.constants import DEFAULT_FREE_PLAN from shared.reports.types import ReportTotals from shared.storage.exceptions import FileNotInStorageError from shared.utils.ReportEncoder import ReportEncoder @@ -244,7 +244,7 @@ def test_create_account(self, dbsession): dbsession.refresh(account) assert account.name == "test_name" assert account.is_active is True - assert account.plan == PlanName.BASIC_PLAN_NAME.value + assert account.plan == DEFAULT_FREE_PLAN assert account.plan_seat_count == 1 assert account.free_seat_count == 0 assert account.plan_auto_activate is True diff --git a/requirements.in b/requirements.in index 91b4c5265..684a752d5 100644 --- a/requirements.in +++ b/requirements.in @@ -1,5 +1,5 @@ https://github.com/codecov/test-results-parser/archive/190bbc8a911099749928e13d5fe57f6027ca1e74.tar.gz#egg=test-results-parser -https://github.com/codecov/shared/archive/986a0971a633eac2a3005947102cb5f4d9119989.tar.gz#egg=shared +https://github.com/codecov/shared/archive/016a756f2ab982016bc2d46e2467be71604c0ba5.tar.gz#egg=shared https://github.com/codecov/timestring/archive/d37ceacc5954dff3b5bd2f887936a98a668dda42.tar.gz#egg=timestring asgiref>=3.7.2 analytics-python==1.3.0b1 diff --git a/requirements.txt b/requirements.txt index e516df1e3..c76add84b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,7 @@ # This file was autogenerated by uv via the following command: # uv pip compile requirements.in -o requirements.txt +amplitude-analytics==1.1.4 + # via shared amqp==5.2.0 # via kombu analytics-python==1.3.0b1 @@ -377,7 +379,7 @@ sentry-sdk==2.13.0 # shared setuptools==75.7.0 # via nodeenv -shared @ https://github.com/codecov/shared/archive/986a0971a633eac2a3005947102cb5f4d9119989.tar.gz#egg=shared +shared @ https://github.com/codecov/shared/archive/016a756f2ab982016bc2d46e2467be71604c0ba5.tar.gz#egg=shared # via -r requirements.in six==1.16.0 # via diff --git a/services/tests/test_decoration.py b/services/tests/test_decoration.py index 1bd980896..8ff0713d7 100644 --- a/services/tests/test_decoration.py +++ b/services/tests/test_decoration.py @@ -13,7 +13,7 @@ from shared.django_apps.reports.tests.factories import ( UploadFactory as DjangoUploadFactory, ) -from shared.plan.constants import PlanName +from shared.plan.constants import DEFAULT_FREE_PLAN from shared.plan.service import PlanService from shared.upload.utils import UploaderType, insert_coverage_measurement from shared.utils.test_utils import mock_config_helper @@ -229,7 +229,7 @@ def test_decoration_type_basic_plan_upload_limit( dbsession.add(pr_author) dbsession.flush() - enriched_pull.database_pull.repository.owner.plan = "users-basic" + enriched_pull.database_pull.repository.owner.plan = DEFAULT_FREE_PLAN enriched_pull.database_pull.repository.private = True commit = CommitFactory.create( @@ -356,7 +356,7 @@ def test_decoration_type_unlimited_upload_on_enterprise( dbsession.add(pr_author) dbsession.flush() - enriched_pull.database_pull.repository.owner.plan = "users-basic" + enriched_pull.database_pull.repository.owner.plan = DEFAULT_FREE_PLAN enriched_pull.database_pull.repository.private = True commit = CommitFactory.create( @@ -392,7 +392,7 @@ def test_uploads_used_with_expired_trial(self, mocker): trial_status=TrialStatus.EXPIRED.value, trial_start_date=datetime.now() + timedelta(days=-10), trial_end_date=datetime.now() + timedelta(days=-2), - plan=PlanName.BASIC_PLAN_NAME.value, + plan=DEFAULT_FREE_PLAN, ) repository = DjangoRepositoryFactory( author=owner, @@ -507,7 +507,7 @@ def test_get_decoration_type_for_users_plan(self, dbsession): owner__username="drazisil-org", owner__service="github", owner__unencrypted_oauth_token="testtfasdfasdflxuu2kfer2ef23", - owner__plan=PlanName.BASIC_PLAN_NAME.value, + owner__plan=DEFAULT_FREE_PLAN, private=True, ) dbsession.add(repository) @@ -706,11 +706,11 @@ def test_get_decoration_type_should_attempt_pr_author_auto_activation( ) @pytest.mark.django_db - def test_get_decoration_type_should_attempt_pr_author_auto_activation_users_free( + def test_get_decoration_type_should_attempt_pr_author_auto_activation_users_developer( self, dbsession, mocker, enriched_pull ): - enriched_pull.database_pull.repository.owner.plan = "users-free" - enriched_pull.database_pull.repository.owner.plan_user_count = 5 + enriched_pull.database_pull.repository.owner.plan = DEFAULT_FREE_PLAN + enriched_pull.database_pull.repository.owner.plan_user_count = 1 enriched_pull.database_pull.repository.owner.plan_activated_users = [] enriched_pull.database_pull.repository.owner.plan_auto_activate = True @@ -961,7 +961,7 @@ def test_uploads_used_with_expired_trial(self, mocker, dbsession): trial_status=TrialStatus.EXPIRED.value, trial_start_date=datetime.now() + timedelta(days=-10), trial_end_date=datetime.now() + timedelta(days=-2), - plan=PlanName.BASIC_PLAN_NAME.value, + plan=DEFAULT_FREE_PLAN, ) repository = DjangoRepositoryFactory( author=owner, diff --git a/services/tests/test_test_results.py b/services/tests/test_test_results.py index b09efe699..2e749d892 100644 --- a/services/tests/test_test_results.py +++ b/services/tests/test_test_results.py @@ -1,5 +1,6 @@ import mock import pytest +from shared.plan.constants import DEFAULT_FREE_PLAN from shared.torngit.exceptions import TorngitClientError from database.models import UploadError @@ -240,9 +241,9 @@ def test_notify_fail_torngit_error( "config,feature_flag,private,plan,ex_result", [ (False, True, False, "users-inappm", False), - (True, True, True, "users-basic", True), - (True, False, False, "users-basic", True), - (True, False, True, "users-basic", False), + (True, True, True, DEFAULT_FREE_PLAN, True), + (True, False, False, DEFAULT_FREE_PLAN, True), + (True, False, True, DEFAULT_FREE_PLAN, False), (True, False, False, "users-inappm", True), (True, False, True, "users-inappm", True), ], diff --git a/tasks/tests/integration/test_upload_e2e.py b/tasks/tests/integration/test_upload_e2e.py index 44f87163a..0bba750a9 100644 --- a/tasks/tests/integration/test_upload_e2e.py +++ b/tasks/tests/integration/test_upload_e2e.py @@ -21,6 +21,7 @@ from services.report import ReportService from tasks.tests.utils import hook_repo_provider, hook_session, run_tasks from tasks.upload import upload_task +from tests.helpers import mock_all_plans_and_tiers def write_raw_upload( @@ -171,6 +172,7 @@ def test_full_upload( mock_storage, mock_configuration, ): + mock_all_plans_and_tiers() setup_mocks(mocker, dbsession, mock_configuration, mock_repo_provider) repository = RepositoryFactory.create() @@ -377,6 +379,7 @@ def test_full_carryforward( mock_storage, mock_configuration, ): + mock_all_plans_and_tiers() user_yaml = {"flag_management": {"default_rules": {"carryforward": True}}} setup_mocks( mocker, dbsession, mock_configuration, mock_repo_provider, user_yaml=user_yaml diff --git a/tasks/tests/unit/test_base.py b/tasks/tests/unit/test_base.py index 3203e39f1..00a38860b 100644 --- a/tasks/tests/unit/test_base.py +++ b/tasks/tests/unit/test_base.py @@ -22,6 +22,7 @@ from database.tests.factories.core import OwnerFactory, RepositoryFactory from tasks.base import BaseCodecovRequest, BaseCodecovTask from tasks.base import celery_app as base_celery_app +from tests.helpers import mock_all_plans_and_tiers here = Path(__file__) @@ -538,9 +539,11 @@ def test_apply_async_override_with_chain(self, mocker): ) @pytest.mark.freeze_time("2023-06-13T10:01:01.000123") + @pytest.mark.django_db(databases={"default"}) def test_real_example_no_override( self, mocker, dbsession, mock_configuration, fake_repos ): + mock_all_plans_and_tiers() mock_configuration.set_params( { "setup": { @@ -583,9 +586,11 @@ def test_real_example_no_override( ) @pytest.mark.freeze_time("2023-06-13T10:01:01.000123") + @pytest.mark.django_db(databases={"default"}) def test_real_example_override_from_celery( self, mocker, dbsession, mock_configuration, fake_repos ): + mock_all_plans_and_tiers() mock_configuration.set_params( { "setup": { @@ -628,9 +633,11 @@ def test_real_example_override_from_celery( ) @pytest.mark.freeze_time("2023-06-13T10:01:01.000123") + @pytest.mark.django_db(databases={"default"}) def test_real_example_override_from_upload( self, mocker, dbsession, mock_configuration, fake_repos ): + mock_all_plans_and_tiers() mock_configuration.set_params( { "setup": { diff --git a/tasks/tests/unit/test_notify_task.py b/tasks/tests/unit/test_notify_task.py index 889e76301..593f5b8a1 100644 --- a/tasks/tests/unit/test_notify_task.py +++ b/tasks/tests/unit/test_notify_task.py @@ -51,6 +51,7 @@ _possibly_refresh_previous_selection, get_ta_relevant_context, ) +from tests.helpers import mock_all_plans_and_tiers def _start_upload_flow(mocker): @@ -213,9 +214,11 @@ def test_determine_decoration_type_from_pull_auto_activation_fails( ) assert not mock_schedule_new_user_activated_task.called + @pytest.mark.django_db(databases={"default"}) def test_determine_decoration_type_from_pull_attempt_activation( self, dbsession, mocker, enriched_pull, with_sql_functions ): + mock_all_plans_and_tiers() pr_author = OwnerFactory.create( username=enriched_pull.provider_pull["author"]["username"], service_id=enriched_pull.provider_pull["author"]["id"], diff --git a/tasks/tests/unit/test_sync_repos_task.py b/tasks/tests/unit/test_sync_repos_task.py index 70e09ff57..3e0204b33 100644 --- a/tasks/tests/unit/test_sync_repos_task.py +++ b/tasks/tests/unit/test_sync_repos_task.py @@ -22,6 +22,7 @@ from database.tests.factories import OwnerFactory, RepositoryFactory from tasks.sync_repo_languages_gql import SyncRepoLanguagesGQLTask from tasks.sync_repos import SyncReposTask +from tests.helpers import mock_all_plans_and_tiers here = Path(__file__) @@ -458,6 +459,7 @@ def test_sync_repos_lock_error(self, dbsession, mock_redis): @respx.mock @pytest.mark.django_db(databases={"default"}) def test_only_public_repos_not_in_db(self, dbsession): + mock_all_plans_and_tiers() token = "ecd73a086eadc85db68747a66bdbd662a785a072" user = OwnerFactory.create( organizations=[], @@ -497,6 +499,7 @@ def test_sync_repos_using_integration( mock_owner_provider, mock_redis, ): + mock_all_plans_and_tiers() user = OwnerFactory.create( organizations=[], service="github", @@ -597,10 +600,12 @@ def repo_obj(service_id, name, language, private, branch, using_integration): @reuse_cassette( "tasks/tests/unit/cassetes/test_sync_repos_task/TestSyncReposTaskUnit/test_sync_repos_using_integration_no_repos.yaml" ) + @pytest.mark.django_db(databases={"default"}) def test_sync_repos_using_integration_no_repos( self, dbsession, ): + mock_all_plans_and_tiers() token = "ecd73a086eadc85db68747a66bdbd662a785a072" user = OwnerFactory.create( organizations=[], @@ -660,12 +665,14 @@ def test_sync_repos_using_integration_no_repos( SoftTimeLimitExceeded(), ], ) + @pytest.mark.django_db(databases={"default"}) def test_sync_repos_list_repos_error( self, dbsession, mock_owner_provider, list_repos_error, ): + mock_all_plans_and_tiers() token = "ecd73a086eadc85db68747a66bdbd662a785a072" user = OwnerFactory.create( organizations=[], @@ -720,7 +727,9 @@ async def mock_list_repos_generator(*args, **kwargs): "tasks/tests/unit/cassetes/test_sync_repos_task/TestSyncReposTaskUnit/test_only_public_repos_not_in_db.yaml" ) @respx.mock + @pytest.mark.django_db(databases={"default"}) def test_insert_repo_and_call_repo_sync_languages(self, dbsession): + mock_all_plans_and_tiers() token = "ecd73a086eadc85db68747a66bdbd662a785a072" user = OwnerFactory.create( organizations=[], @@ -926,6 +935,7 @@ def repo_obj(service_id, name, language, private, branch, using_integration): mocked_app.tasks[sync_repo_languages_task_name].apply_async.assert_not_called() + @pytest.mark.django_db(databases={"default"}) def test_sync_repos_using_integration_affected_repos_known( self, mocker, @@ -933,6 +943,7 @@ def test_sync_repos_using_integration_affected_repos_known( mock_owner_provider, mock_redis, ): + mock_all_plans_and_tiers() user = OwnerFactory.create( organizations=[], service="github", diff --git a/tasks/tests/unit/test_test_results_finisher.py b/tasks/tests/unit/test_test_results_finisher.py index 0b8189a76..2f02e0ea0 100644 --- a/tasks/tests/unit/test_test_results_finisher.py +++ b/tasks/tests/unit/test_test_results_finisher.py @@ -3,7 +3,7 @@ import pytest from mock import AsyncMock -from shared.plan.constants import PlanName +from shared.plan.constants import DEFAULT_FREE_PLAN, PlanName from shared.torngit.exceptions import TorngitClientError from database.enums import ReportType @@ -1159,7 +1159,7 @@ def test_upload_finisher_task_call_computed_name( @pytest.mark.integration @pytest.mark.django_db - @pytest.mark.parametrize("plan", ["users-basic", "users-pr-inappm"]) + @pytest.mark.parametrize("plan", [DEFAULT_FREE_PLAN, "users-pr-inappm"]) def test_upload_finisher_task_call_main_with_plan( self, mocker, diff --git a/tests/helpers.py b/tests/helpers.py index 56d82d6b8..be3df03f2 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -1,6 +1,6 @@ from shared.django_apps.codecov_auth.models import BillingRate from shared.django_apps.codecov_auth.tests.factories import PlanFactory, TierFactory -from shared.plan.constants import PlanName, PlanPrice, TierName +from shared.plan.constants import DEFAULT_FREE_PLAN, PlanName, PlanPrice, TierName def mock_all_plans_and_tiers(): @@ -20,7 +20,7 @@ def mock_all_plans_and_tiers(): basic_tier = TierFactory(tier_name=TierName.BASIC.value) PlanFactory( - name=PlanName.BASIC_PLAN_NAME.value, + name=DEFAULT_FREE_PLAN, tier=basic_tier, marketing_name="Developer", benefits=[ @@ -30,17 +30,6 @@ def mock_all_plans_and_tiers(): ], monthly_uploads_limit=250, ) - PlanFactory( - name=PlanName.FREE_PLAN_NAME.value, - tier=basic_tier, - marketing_name="Developer", - benefits=[ - "Up to 1 user", - "Unlimited public repositories", - "Unlimited private repositories", - ], - ) - pro_tier = TierFactory(tier_name=TierName.PRO.value) PlanFactory( name=PlanName.CODECOV_PRO_MONTHLY.value,