support: Raise errors for support requests that are not processed.

Previously, the message string was sent as a success response to
the context, which could have been confusing or ignored when shown
in the support admin view.
This commit is contained in:
Lauryn Menard 2024-01-03 20:22:49 +01:00 committed by Tim Abbott
parent 880133295e
commit cc957e92f4
3 changed files with 43 additions and 15 deletions

View File

@ -54,6 +54,7 @@ if settings.BILLING_ENABLED:
RealmBillingSession,
RemoteRealmBillingSession,
RemoteServerBillingSession,
SupportRequestError,
SupportType,
SupportViewRequest,
cents_to_dollar_string,
@ -265,8 +266,11 @@ def support(
billing_session = RealmBillingSession(
user=acting_user, realm=realm, support_session=True
)
success_message = billing_session.process_support_view_request(support_view_request)
context["success_message"] = success_message
try:
success_message = billing_session.process_support_view_request(support_view_request)
context["success_message"] = success_message
except SupportRequestError as error:
context["error_message"] = error.msg
if query:
key_words = get_invitee_emails_set(query)
@ -466,14 +470,21 @@ def remote_servers_support(
)
if support_view_request is not None:
if remote_realm_support_request:
success_message = RemoteRealmBillingSession(
support_staff=acting_user, remote_realm=remote_realm
).process_support_view_request(support_view_request)
try:
success_message = RemoteRealmBillingSession(
support_staff=acting_user, remote_realm=remote_realm
).process_support_view_request(support_view_request)
context["success_message"] = success_message
except SupportRequestError as error:
context["error_message"] = error.msg
else:
success_message = RemoteServerBillingSession(
support_staff=acting_user, remote_server=remote_server
).process_support_view_request(support_view_request)
context["success_message"] = success_message
try:
success_message = RemoteServerBillingSession(
support_staff=acting_user, remote_server=remote_server
).process_support_view_request(support_view_request)
context["success_message"] = success_message
except SupportRequestError as error:
context["error_message"] = error.msg
email_to_search = None
hostname_to_search = None

View File

@ -434,6 +434,14 @@ class InvalidTierError(Exception):
super().__init__(self.message)
class SupportRequestError(BillingError):
def __init__(self, message: str) -> None:
super().__init__(
"invalid support request",
message,
)
def catch_stripe_errors(func: Callable[ParamT, ReturnT]) -> Callable[ParamT, ReturnT]:
@wraps(func)
def wrapped(*args: ParamT.args, **kwargs: ParamT.kwargs) -> ReturnT:
@ -1164,12 +1172,12 @@ class BillingSession(ABC):
f"Cannot upgrade from {plan.name} to {CustomerPlan.name_from_tier(new_plan_tier)}"
)
def check_customer_not_on_paid_plan(self, customer: Customer) -> str: # nocoverage
def check_customer_not_on_paid_plan(self, customer: Customer) -> str:
current_plan = get_current_plan_by_customer(customer)
if current_plan is not None:
# Check if the customer is scheduled for an upgrade.
next_plan = self.get_next_plan(current_plan)
if next_plan is not None:
if next_plan is not None: # nocoverage
return f"Customer scheduled for upgrade to {next_plan.name}. Please cancel upgrade before approving sponsorship!"
# It is fine to end legacy plan not scheduled for an upgrade.
@ -3037,8 +3045,8 @@ class RealmBillingSession(BillingSession):
customer = self.get_customer()
if customer is not None:
error_message = self.check_customer_not_on_paid_plan(customer)
if error_message != "": # nocoverage
return error_message
if error_message != "":
raise SupportRequestError(error_message)
from zerver.actions.message_send import internal_send_private_message
@ -3398,7 +3406,7 @@ class RemoteRealmBillingSession(BillingSession):
if customer is not None:
error_message = self.check_customer_not_on_paid_plan(customer)
if error_message != "":
return error_message
raise SupportRequestError(error_message)
if self.remote_realm.plan_type == RemoteRealm.PLAN_TYPE_SELF_MANAGED_LEGACY:
plan = get_current_plan_by_customer(customer)
@ -3814,7 +3822,7 @@ class RemoteServerBillingSession(BillingSession):
if customer is not None:
error_message = self.check_customer_not_on_paid_plan(customer)
if error_message != "":
return error_message
raise SupportRequestError(error_message)
if self.remote_server.plan_type == RemoteZulipServer.PLAN_TYPE_SELF_MANAGED_LEGACY:
plan = get_current_plan_by_customer(customer)

View File

@ -56,6 +56,7 @@ from corporate.lib.stripe import (
RemoteRealmBillingSession,
RemoteServerBillingSession,
StripeCardError,
SupportRequestError,
SupportType,
SupportViewRequest,
add_months,
@ -5393,6 +5394,14 @@ class TestSupportBillingHelpers(StripeTestCase):
self.assertEqual(realm_audit_log.extra_data, expected_extra_data)
self.assertEqual(realm_audit_log.acting_user, support_admin)
# Confirm that once a plan has been purchased and is active,
# approving a full sponsorship (our version of 100% discount) fails.
with self.assertRaisesRegex(
SupportRequestError,
"Customer on plan Zulip Cloud Standard. Please end current plan before approving sponsorship!",
):
billing_session.approve_sponsorship()
def test_approve_realm_sponsorship(self) -> None:
realm = get_realm("zulip")
self.assertNotEqual(realm.plan_type, Realm.PLAN_TYPE_STANDARD_FREE)