From 34f62e7df69409d23556f720d52e1d4de5bfdbae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Mon, 29 Jun 2026 17:45:54 +0800 Subject: [PATCH] fix: editor should not query billing subscriptions (#38157) --- .../billing/billing-integration.test.tsx | 18 ++++++++++++--- .../billing-page/__tests__/index.spec.tsx | 22 +++++++++++++------ .../components/billing/billing-page/index.tsx | 4 ++-- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/web/__tests__/billing/billing-integration.test.tsx b/web/__tests__/billing/billing-integration.test.tsx index e82a6d8eac2..d173392a420 100644 --- a/web/__tests__/billing/billing-integration.test.tsx +++ b/web/__tests__/billing/billing-integration.test.tsx @@ -232,7 +232,20 @@ describe('Billing Page + Plan Integration', () => { // Verify billing URL button visibility and behavior describe('Billing URL button', () => { - it('should show billing button when subscription management permission is granted', () => { + it('should show billing button when manager has subscription management permission', () => { + setupProviderContext({ type: Plan.sandbox }) + setupAppContext({ + isCurrentWorkspaceManager: true, + workspacePermissionKeys: ['billing.subscription.manage'], + }) + + render() + + expect(screen.getByText(/viewBillingTitle/i)).toBeInTheDocument() + expect(screen.getByText(/viewBillingAction/i)).toBeInTheDocument() + }) + + it('should hide billing button when subscription management permission is granted without manager role', () => { setupProviderContext({ type: Plan.sandbox }) setupAppContext({ isCurrentWorkspaceManager: false, @@ -241,8 +254,7 @@ describe('Billing Page + Plan Integration', () => { render() - expect(screen.getByText(/viewBillingTitle/i)).toBeInTheDocument() - expect(screen.getByText(/viewBillingAction/i)).toBeInTheDocument() + expect(screen.queryByText(/viewBillingTitle/i)).not.toBeInTheDocument() }) it('should hide billing button when subscription management permission is missing', () => { diff --git a/web/app/components/billing/billing-page/__tests__/index.spec.tsx b/web/app/components/billing/billing-page/__tests__/index.spec.tsx index d9f296e7978..07d6e62131a 100644 --- a/web/app/components/billing/billing-page/__tests__/index.spec.tsx +++ b/web/app/components/billing/billing-page/__tests__/index.spec.tsx @@ -6,6 +6,7 @@ let fetching = false let isManager = true let enableBilling = true let workspacePermissionKeys: string[] = ['billing.subscription.manage'] +let billingUrlEnabled = false const refetchMock = vi.fn() const openAsyncWindowMock = vi.fn() @@ -19,11 +20,14 @@ type BillingWindowOptions = { type OpenAsyncWindowCall = [BillingUrlCallback, BillingWindowOptions] vi.mock('@/service/use-billing', () => ({ - useBillingUrl: () => ({ - data: currentBillingUrl, - isFetching: fetching, - refetch: refetchMock, - }), + useBillingUrl: (enabled: boolean) => { + billingUrlEnabled = enabled + return { + data: currentBillingUrl, + isFetching: fetching, + refetch: refetchMock, + } + }, })) vi.mock('@/hooks/use-async-window-open', () => ({ @@ -54,28 +58,32 @@ describe('Billing', () => { fetching = false isManager = true enableBilling = true + billingUrlEnabled = false workspacePermissionKeys = ['billing.subscription.manage'] refetchMock.mockResolvedValue({ data: 'https://billing' }) }) - it('shows the billing action when subscription management permission is granted without manager role', () => { + it('hides the billing action when subscription management permission is granted without manager role', () => { isManager = false render() - expect(screen.getByRole('button', { name: /billing\.viewBillingTitle/ })).toBeInTheDocument() + expect(screen.queryByRole('button', { name: /billing\.viewBillingTitle/ })).not.toBeInTheDocument() + expect(billingUrlEnabled).toBe(false) }) it('hides the billing action when subscription management permission is missing or billing is disabled', () => { workspacePermissionKeys = [] render() expect(screen.queryByRole('button', { name: /billing\.viewBillingTitle/ })).not.toBeInTheDocument() + expect(billingUrlEnabled).toBe(false) vi.clearAllMocks() workspacePermissionKeys = ['billing.subscription.manage'] enableBilling = false render() expect(screen.queryByRole('button', { name: /billing\.viewBillingTitle/ })).not.toBeInTheDocument() + expect(billingUrlEnabled).toBe(false) }) it('opens the billing window with the immediate url when the button is clicked', async () => { diff --git a/web/app/components/billing/billing-page/index.tsx b/web/app/components/billing/billing-page/index.tsx index 4b1d4424c04..d518810c668 100644 --- a/web/app/components/billing/billing-page/index.tsx +++ b/web/app/components/billing/billing-page/index.tsx @@ -11,9 +11,9 @@ import PlanComp from '../plan' const Billing: FC = () => { const { t } = useTranslation() - const { workspacePermissionKeys } = useAppContext() + const { isCurrentWorkspaceManager, workspacePermissionKeys } = useAppContext() const { enableBilling } = useProviderContext() - const canManageBillingSubscription = hasPermission(workspacePermissionKeys, BillingPermission.SubscriptionManage) + const canManageBillingSubscription = isCurrentWorkspaceManager && hasPermission(workspacePermissionKeys, BillingPermission.SubscriptionManage) const { data: billingUrl, isFetching, refetch } = useBillingUrl(enableBilling && canManageBillingSubscription) const openAsyncWindow = useAsyncWindowOpen()