codecov-api
codecov-api copied to clipboard
feat: Export plans and tiers to CSV
Purpose/Motivation
What is the feature? Why is this being done? Adding a new generic function that allows you to export data from Django portal and feed it to your local DB.
Links to relevant tickets
https://github.com/codecov/engineering-team/issues/3288
Legal Boilerplate
Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. In 2022 this entity acquired Codecov and as result Sentry is going to need some rights from me in order to utilize my contributions in this PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.
Codecov Report
All modified and coverable lines are covered by tests :white_check_mark:
:white_check_mark: All tests successful. No failed tests found.
:loudspeaker: Thoughts on this report? Let us know!
:x: 53 Tests Failed:
| Tests completed | Failed | Passed | Skipped |
|---|---|---|---|
| 2737 | 53 | 2684 | 7 |
View the top 3 failed tests by shortest run time
services/tests/test_billing.py::BillingServiceTests::test_update_plan_to_users_basic_sets_plan_if_no_subscription_idStack Traces | 0.013s run time
self = <services.tests.test_billing.BillingServiceTests testMethod=test_update_plan_to_users_basic_sets_plan_if_no_subscription_id> delete_subscription_mock = <MagicMock name='delete_subscription' id='140689237058544'> modify_subscription_mock = <MagicMock name='modify_subscription' id='140689237052592'> create_checkout_session_mock = <MagicMock name='create_checkout_session' id='140689217159392'> set_default_plan_data = <MagicMock name='set_default_plan_data' id='140689217163328'> @patch("shared.plan.service.PlanService.set_default_plan_data") @patch("services.tests.test_billing.MockPaymentService.create_checkout_session") @patch("services.tests.test_billing.MockPaymentService.modify_subscription") @patch("services.tests.test_billing.MockPaymentService.delete_subscription") def test_update_plan_to_users_basic_sets_plan_if_no_subscription_id( self, delete_subscription_mock, modify_subscription_mock, create_checkout_session_mock, set_default_plan_data, ): owner = OwnerFactory() > self.billing_service.update_plan( owner, {"value": PlanName.BASIC_PLAN_NAME.value} ) services/tests/test_billing.py:2162: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ services/billing.py:929: in update_plan plan_service = PlanService(current_org=owner) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <shared.plan.service.PlanService object at 0x7ff4cc38f830> current_org = <Owner: Owner<github/ashley66>> def __init__(self, current_org: Owner): """ Initializes a PlanService object for a specific organization. Args: current_org (Owner): The organization for which the plan service is being initialized. Raises: ValueError: If the organization's plan is unsupported. """ if ( current_org.service == Service.GITLAB.value and current_org.parent_service_id ): # for GitLab groups and subgroups, use the plan on the root org self.current_org = current_org.root_organization else: self.current_org = current_org if not Plan.objects.filter(name=self.current_org.plan).exists(): > raise ValueError("Unsupported plan") E ValueError: Unsupported plan .../local/lib/python3.12.../shared/plan/service.py:54: ValueError
billing/tests/test_helpers.py::HelpersTestCase::test_on_enterprise_plan_on_premStack Traces | 0.017s run time
self = <billing.tests.test_helpers.HelpersTestCase testMethod=test_on_enterprise_plan_on_prem> @override_settings(IS_ENTERPRISE=True) def test_on_enterprise_plan_on_prem(self): owner = OwnerFactory() > assert on_enterprise_plan(owner) == True billing/tests/test_helpers.py:17: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ billing/helpers.py:11: in on_enterprise_plan plan = Plan.objects.select_related("tier").get(name=owner.plan) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <QuerySet [<Plan: users-trial>, <Plan: users-free>, <Plan: users-basic>, <Plan: users-pr-inappy>, <Plan: users-pr-inap...lan: users-teamm>, <Plan: users-sentryy>, <Plan: users-sentrym>, <Plan: users-enterprisey>, <Plan: users-enterprisem>]> args = (), kwargs = {'name': 'users-developer'}, clone = <QuerySet []> limit = 21, num = 0 def get(self, *args, **kwargs): """ Perform the query and return a single object matching the given keyword arguments. """ if self.query.combinator and (args or kwargs): raise NotSupportedError( "Calling QuerySet.get(...) with filters after %s() is not " "supported." % self.query.combinator ) clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs) if self.query.can_filter() and not self.query.distinct_fields: clone = clone.order_by() limit = None if ( not clone.query.select_for_update or connections[clone.db].features.supports_select_for_update_with_limit ): limit = MAX_GET_RESULTS clone.query.set_limits(high=limit) num = len(clone) if num == 1: return clone._result_cache[0] if not num: > raise self.model.DoesNotExist( "%s matching query does not exist." % self.model._meta.object_name ) E shared.django_apps.codecov_auth.models.Plan.DoesNotExist: Plan matching query does not exist. .../local/lib/python3.12.../db/models/query.py:637: DoesNotExist
services/tests/test_billing.py::StripeServiceTests::test_apply_cancellation_discount_existing_couponStack Traces | 0.017s run time
self = <services.tests.test_billing.StripeServiceTests testMethod=test_apply_cancellation_discount_existing_coupon> customer_modify_mock = <MagicMock name='modify' id='140689377339744'> coupon_create_mock = <MagicMock name='create' id='140689377330048'> @patch("services.billing.stripe.Coupon.create") @patch("services.billing.stripe.Customer.modify") def test_apply_cancellation_discount_existing_coupon( self, customer_modify_mock, coupon_create_mock ): owner = OwnerFactory( stripe_customer_id="test-customer-id", stripe_subscription_id="test-subscription-id", stripe_coupon_id="test-coupon-id", ) > self.stripe.apply_cancellation_discount(owner) services/tests/test_billing.py:1896: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ services/billing.py:27: in catch_and_raise return method(*args, **kwargs) services/billing.py:713: in apply_cancellation_discount plan_service = PlanService(current_org=owner) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <shared.plan.service.PlanService object at 0x7ff4cc8d7830> current_org = <Owner: Owner<github/charlesowens>> def __init__(self, current_org: Owner): """ Initializes a PlanService object for a specific organization. Args: current_org (Owner): The organization for which the plan service is being initialized. Raises: ValueError: If the organization's plan is unsupported. """ if ( current_org.service == Service.GITLAB.value and current_org.parent_service_id ): # for GitLab groups and subgroups, use the plan on the root org self.current_org = current_org.root_organization else: self.current_org = current_org if not Plan.objects.filter(name=self.current_org.plan).exists(): > raise ValueError("Unsupported plan") E ValueError: Unsupported plan .../local/lib/python3.12.../shared/plan/service.py:54: ValueError
To view more test analytics, go to the Test Analytics Dashboard :loudspeaker: Thoughts on this report? Let us know!
:x: 53 Tests Failed:
| Tests completed | Failed | Passed | Skipped |
|---|---|---|---|
| 2744 | 53 | 2685 | 6 |
View the top 3 failed tests by shortest run time
test_update_plan_to_users_basic_sets_plan_if_no_subscription_idStack Traces | 0.013s run time
self = <services.tests.test_billing.BillingServiceTests testMethod=test_update_plan_to_users_basic_sets_plan_if_no_subscription_id> delete_subscription_mock = <MagicMock name='delete_subscription' id='140689237058544'> modify_subscription_mock = <MagicMock name='modify_subscription' id='140689237052592'> create_checkout_session_mock = <MagicMock name='create_checkout_session' id='140689217159392'> set_default_plan_data = <MagicMock name='set_default_plan_data' id='140689217163328'> @patch("shared.plan.service.PlanService.set_default_plan_data") @patch("services.tests.test_billing.MockPaymentService.create_checkout_session") @patch("services.tests.test_billing.MockPaymentService.modify_subscription") @patch("services.tests.test_billing.MockPaymentService.delete_subscription") def test_update_plan_to_users_basic_sets_plan_if_no_subscription_id( self, delete_subscription_mock, modify_subscription_mock, create_checkout_session_mock, set_default_plan_data, ): owner = OwnerFactory() > self.billing_service.update_plan( owner, {"value": PlanName.BASIC_PLAN_NAME.value} ) services/tests/test_billing.py:2162: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ services/billing.py:929: in update_plan plan_service = PlanService(current_org=owner) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <shared.plan.service.PlanService object at 0x7ff4cc38f830> current_org = <Owner: Owner<github/ashley66>> def __init__(self, current_org: Owner): """ Initializes a PlanService object for a specific organization. Args: current_org (Owner): The organization for which the plan service is being initialized. Raises: ValueError: If the organization's plan is unsupported. """ if ( current_org.service == Service.GITLAB.value and current_org.parent_service_id ): # for GitLab groups and subgroups, use the plan on the root org self.current_org = current_org.root_organization else: self.current_org = current_org if not Plan.objects.filter(name=self.current_org.plan).exists(): > raise ValueError("Unsupported plan") E ValueError: Unsupported plan /usr/local/lib/python3.12/site-packages/shared/plan/service.py:54: ValueError
test_on_enterprise_plan_on_premStack Traces | 0.017s run time
self = <billing.tests.test_helpers.HelpersTestCase testMethod=test_on_enterprise_plan_on_prem> @override_settings(IS_ENTERPRISE=True) def test_on_enterprise_plan_on_prem(self): owner = OwnerFactory() > assert on_enterprise_plan(owner) == True billing/tests/test_helpers.py:17: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ billing/helpers.py:11: in on_enterprise_plan plan = Plan.objects.select_related("tier").get(name=owner.plan) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <QuerySet [<Plan: users-trial>, <Plan: users-free>, <Plan: users-basic>, <Plan: users-pr-inappy>, <Plan: users-pr-inap...lan: users-teamm>, <Plan: users-sentryy>, <Plan: users-sentrym>, <Plan: users-enterprisey>, <Plan: users-enterprisem>]> args = (), kwargs = {'name': 'users-developer'}, clone = <QuerySet []> limit = 21, num = 0 def get(self, *args, **kwargs): """ Perform the query and return a single object matching the given keyword arguments. """ if self.query.combinator and (args or kwargs): raise NotSupportedError( "Calling QuerySet.get(...) with filters after %s() is not " "supported." % self.query.combinator ) clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs) if self.query.can_filter() and not self.query.distinct_fields: clone = clone.order_by() limit = None if ( not clone.query.select_for_update or connections[clone.db].features.supports_select_for_update_with_limit ): limit = MAX_GET_RESULTS clone.query.set_limits(high=limit) num = len(clone) if num == 1: return clone._result_cache[0] if not num: > raise self.model.DoesNotExist( "%s matching query does not exist." % self.model._meta.object_name ) E shared.django_apps.codecov_auth.models.Plan.DoesNotExist: Plan matching query does not exist. /usr/local/lib/python3.12/site-packages/django/db/models/query.py:637: DoesNotExist
test_apply_cancellation_discount_existing_couponStack Traces | 0.017s run time
self = <services.tests.test_billing.StripeServiceTests testMethod=test_apply_cancellation_discount_existing_coupon> customer_modify_mock = <MagicMock name='modify' id='140689377339744'> coupon_create_mock = <MagicMock name='create' id='140689377330048'> @patch("services.billing.stripe.Coupon.create") @patch("services.billing.stripe.Customer.modify") def test_apply_cancellation_discount_existing_coupon( self, customer_modify_mock, coupon_create_mock ): owner = OwnerFactory( stripe_customer_id="test-customer-id", stripe_subscription_id="test-subscription-id", stripe_coupon_id="test-coupon-id", ) > self.stripe.apply_cancellation_discount(owner) services/tests/test_billing.py:1896: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ services/billing.py:27: in catch_and_raise return method(*args, **kwargs) services/billing.py:713: in apply_cancellation_discount plan_service = PlanService(current_org=owner) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <shared.plan.service.PlanService object at 0x7ff4cc8d7830> current_org = <Owner: Owner<github/charlesowens>> def __init__(self, current_org: Owner): """ Initializes a PlanService object for a specific organization. Args: current_org (Owner): The organization for which the plan service is being initialized. Raises: ValueError: If the organization's plan is unsupported. """ if ( current_org.service == Service.GITLAB.value and current_org.parent_service_id ): # for GitLab groups and subgroups, use the plan on the root org self.current_org = current_org.root_organization else: self.current_org = current_org if not Plan.objects.filter(name=self.current_org.plan).exists(): > raise ValueError("Unsupported plan") E ValueError: Unsupported plan /usr/local/lib/python3.12/site-packages/shared/plan/service.py:54: ValueError
:mega: Thoughts on this report? Let Codecov know! | Powered by Codecov
Codecov Report
All modified and coverable lines are covered by tests :white_check_mark:
Project coverage is 95.92%. Comparing base (
8ed03b4) to head (e2c35cd).
:white_check_mark: All tests successful. No failed tests found.
Additional details and impacted files
@@ Coverage Diff @@
## main #1127 +/- ##
=======================================
Coverage 95.92% 95.92%
=======================================
Files 492 492
Lines 16876 16890 +14
=======================================
+ Hits 16188 16202 +14
Misses 688 688
| Flag | Coverage Δ | |
|---|---|---|
| unit | 95.92% <100.00%> (+<0.01%) |
:arrow_up: |
Flags with carried forward coverage won't be shown. Click here to find out more.
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
This PR includes changes to shared. Please review them here: https://github.com/codecov/shared/compare/c8dca747a7feb93d7c4db6d8845692420b99e676...7ba099fa0552244c77a8cc3a4b772216613c09c8
:x: 53 Tests Failed:
| Tests completed | Failed | Passed | Skipped |
|---|---|---|---|
| 2738 | 53 | 2685 | 6 |
View the top 3 failed tests by shortest run time
services/tests/test_billing.py::BillingServiceTests::test_update_plan_to_users_basic_sets_plan_if_no_subscription_idStack Traces | 0.013s run time
self = <services.tests.test_billing.BillingServiceTests testMethod=test_update_plan_to_users_basic_sets_plan_if_no_subscription_id> delete_subscription_mock = <MagicMock name='delete_subscription' id='140689237058544'> modify_subscription_mock = <MagicMock name='modify_subscription' id='140689237052592'> create_checkout_session_mock = <MagicMock name='create_checkout_session' id='140689217159392'> set_default_plan_data = <MagicMock name='set_default_plan_data' id='140689217163328'> @patch("shared.plan.service.PlanService.set_default_plan_data") @patch("services.tests.test_billing.MockPaymentService.create_checkout_session") @patch("services.tests.test_billing.MockPaymentService.modify_subscription") @patch("services.tests.test_billing.MockPaymentService.delete_subscription") def test_update_plan_to_users_basic_sets_plan_if_no_subscription_id( self, delete_subscription_mock, modify_subscription_mock, create_checkout_session_mock, set_default_plan_data, ): owner = OwnerFactory() > self.billing_service.update_plan( owner, {"value": PlanName.BASIC_PLAN_NAME.value} ) services/tests/test_billing.py:2162: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ services/billing.py:929: in update_plan plan_service = PlanService(current_org=owner) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <shared.plan.service.PlanService object at 0x7ff4cc38f830> current_org = <Owner: Owner<github/ashley66>> def __init__(self, current_org: Owner): """ Initializes a PlanService object for a specific organization. Args: current_org (Owner): The organization for which the plan service is being initialized. Raises: ValueError: If the organization's plan is unsupported. """ if ( current_org.service == Service.GITLAB.value and current_org.parent_service_id ): # for GitLab groups and subgroups, use the plan on the root org self.current_org = current_org.root_organization else: self.current_org = current_org if not Plan.objects.filter(name=self.current_org.plan).exists(): > raise ValueError("Unsupported plan") E ValueError: Unsupported plan .../local/lib/python3.12.../shared/plan/service.py:54: ValueError
billing/tests/test_helpers.py::HelpersTestCase::test_on_enterprise_plan_on_premStack Traces | 0.017s run time
self = <billing.tests.test_helpers.HelpersTestCase testMethod=test_on_enterprise_plan_on_prem> @override_settings(IS_ENTERPRISE=True) def test_on_enterprise_plan_on_prem(self): owner = OwnerFactory() > assert on_enterprise_plan(owner) == True billing/tests/test_helpers.py:17: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ billing/helpers.py:11: in on_enterprise_plan plan = Plan.objects.select_related("tier").get(name=owner.plan) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <QuerySet [<Plan: users-trial>, <Plan: users-free>, <Plan: users-basic>, <Plan: users-pr-inappy>, <Plan: users-pr-inap...lan: users-teamm>, <Plan: users-sentryy>, <Plan: users-sentrym>, <Plan: users-enterprisey>, <Plan: users-enterprisem>]> args = (), kwargs = {'name': 'users-developer'}, clone = <QuerySet []> limit = 21, num = 0 def get(self, *args, **kwargs): """ Perform the query and return a single object matching the given keyword arguments. """ if self.query.combinator and (args or kwargs): raise NotSupportedError( "Calling QuerySet.get(...) with filters after %s() is not " "supported." % self.query.combinator ) clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs) if self.query.can_filter() and not self.query.distinct_fields: clone = clone.order_by() limit = None if ( not clone.query.select_for_update or connections[clone.db].features.supports_select_for_update_with_limit ): limit = MAX_GET_RESULTS clone.query.set_limits(high=limit) num = len(clone) if num == 1: return clone._result_cache[0] if not num: > raise self.model.DoesNotExist( "%s matching query does not exist." % self.model._meta.object_name ) E shared.django_apps.codecov_auth.models.Plan.DoesNotExist: Plan matching query does not exist. .../local/lib/python3.12.../db/models/query.py:637: DoesNotExist
services/tests/test_billing.py::StripeServiceTests::test_apply_cancellation_discount_existing_couponStack Traces | 0.017s run time
self = <services.tests.test_billing.StripeServiceTests testMethod=test_apply_cancellation_discount_existing_coupon> customer_modify_mock = <MagicMock name='modify' id='140689377339744'> coupon_create_mock = <MagicMock name='create' id='140689377330048'> @patch("services.billing.stripe.Coupon.create") @patch("services.billing.stripe.Customer.modify") def test_apply_cancellation_discount_existing_coupon( self, customer_modify_mock, coupon_create_mock ): owner = OwnerFactory( stripe_customer_id="test-customer-id", stripe_subscription_id="test-subscription-id", stripe_coupon_id="test-coupon-id", ) > self.stripe.apply_cancellation_discount(owner) services/tests/test_billing.py:1896: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ services/billing.py:27: in catch_and_raise return method(*args, **kwargs) services/billing.py:713: in apply_cancellation_discount plan_service = PlanService(current_org=owner) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <shared.plan.service.PlanService object at 0x7ff4cc8d7830> current_org = <Owner: Owner<github/charlesowens>> def __init__(self, current_org: Owner): """ Initializes a PlanService object for a specific organization. Args: current_org (Owner): The organization for which the plan service is being initialized. Raises: ValueError: If the organization's plan is unsupported. """ if ( current_org.service == Service.GITLAB.value and current_org.parent_service_id ): # for GitLab groups and subgroups, use the plan on the root org self.current_org = current_org.root_organization else: self.current_org = current_org if not Plan.objects.filter(name=self.current_org.plan).exists(): > raise ValueError("Unsupported plan") E ValueError: Unsupported plan .../local/lib/python3.12.../shared/plan/service.py:54: ValueError
To view more test analytics, go to the Test Analytics Dashboard :loudspeaker: Thoughts on this report? Let us know!
@codecov-ai-reviewer review
On it! We are reviewing the PR and will provide feedback shortly.