From 1c9527654dc0bb23003e6418c634551008fbca9e Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Thu, 31 Oct 2024 10:26:47 +0100 Subject: [PATCH] feat: traffic limits for enterprise-payg (#8596) --- .../NetworkTrafficUsage.tsx | 7 +- .../hooks/useTrafficLimit.test.ts | 77 +++++++++++++++++++ .../hooks/useTrafficLimit.ts | 24 ++++++ frontend/src/interfaces/uiConfig.ts | 1 + src/lib/types/experimental.ts | 5 ++ 5 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 frontend/src/component/admin/network/NetworkTrafficUsage/hooks/useTrafficLimit.test.ts create mode 100644 frontend/src/component/admin/network/NetworkTrafficUsage/hooks/useTrafficLimit.ts diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx index 7735b3992a..92176b790e 100644 --- a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx @@ -31,6 +31,7 @@ import { } from 'hooks/useTrafficData'; import { customHighlightPlugin } from 'component/common/Chart/customHighlightPlugin'; import { formatTickValue } from 'component/common/Chart/formatTickValue'; +import { useTrafficLimit } from './hooks/useTrafficLimit'; const StyledBox = styled(Box)(({ theme }) => ({ display: 'grid', @@ -136,13 +137,11 @@ const createBarChartOptions = ( }, }); -const proPlanIncludedRequests = 53_000_000; - export const NetworkTrafficUsage: VFC = () => { usePageTitle('Network - Data Usage'); const theme = useTheme(); - const { isOss, isPro } = useUiConfig(); + const { isOss } = useUiConfig(); const { record, @@ -157,7 +156,7 @@ export const NetworkTrafficUsage: VFC = () => { calculateEstimatedMonthlyCost, } = useTrafficDataEstimation(); - const includedTraffic = isPro() ? proPlanIncludedRequests : 0; + const includedTraffic = useTrafficLimit(); const options = useMemo(() => { return createBarChartOptions( diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/hooks/useTrafficLimit.test.ts b/frontend/src/component/admin/network/NetworkTrafficUsage/hooks/useTrafficLimit.test.ts new file mode 100644 index 0000000000..f9dacbe66c --- /dev/null +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/hooks/useTrafficLimit.test.ts @@ -0,0 +1,77 @@ +import { renderHook } from '@testing-library/react'; +import { useTrafficLimit } from './useTrafficLimit'; +import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; +import { useUiFlag } from 'hooks/useUiFlag'; +import { vi, describe, it, expect } from 'vitest'; + +vi.mock('hooks/api/getters/useUiConfig/useUiConfig'); +vi.mock('hooks/useUiFlag'); + +describe('useTrafficLimit', () => { + it('should return requests limit if user is on pro plan', () => { + vi.mocked(useUiConfig).mockReturnValue({ + isPro: () => true, + isEnterprise: () => false, + uiConfig: { + billing: 'pay-as-you-go', + }, + } as any); + vi.mocked(useUiFlag).mockReturnValue(false); + + const { result } = renderHook(() => useTrafficLimit()); + + expect(result.current).toBe(53_000_000); + }); + + it('should return PAYG plan requests limit if enterprise-payg is enabled and billing is pay-as-you-go', () => { + vi.mocked(useUiConfig).mockReturnValue({ + isPro: () => false, + isEnterprise: () => true, + uiConfig: { billing: 'pay-as-you-go' }, + } as any); + vi.mocked(useUiFlag).mockReturnValue(true); + + const { result } = renderHook(() => useTrafficLimit()); + + expect(result.current).toBe(53_000_000); + }); + + it('should return 0 if user is not on pro plan and pay-as-you-go conditions are not met', () => { + vi.mocked(useUiConfig).mockReturnValue({ + isPro: () => false, + isEnterprise: () => false, + uiConfig: {}, + } as any); + vi.mocked(useUiFlag).mockReturnValue(false); + + const { result } = renderHook(() => useTrafficLimit()); + + expect(result.current).toBe(0); + }); + + it('should return 0 if user is not on pro plan and flag is disabled', () => { + vi.mocked(useUiConfig).mockReturnValue({ + isPro: () => false, + isEnterprise: () => true, + uiConfig: { billing: 'pay-as-you-go' }, + } as any); + vi.mocked(useUiFlag).mockReturnValue(false); + + const { result } = renderHook(() => useTrafficLimit()); + + expect(result.current).toBe(0); + }); + + it('should return 0 if enterprise PAYG is enabled but billing is not pay-as-you-go', () => { + vi.mocked(useUiConfig).mockReturnValue({ + isPro: () => false, + isEnterprise: () => false, + uiConfig: { billing: 'subscription' }, + } as any); + vi.mocked(useUiFlag).mockReturnValue(true); + + const { result } = renderHook(() => useTrafficLimit()); + + expect(result.current).toBe(0); + }); +}); diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/hooks/useTrafficLimit.ts b/frontend/src/component/admin/network/NetworkTrafficUsage/hooks/useTrafficLimit.ts new file mode 100644 index 0000000000..688b78b7dd --- /dev/null +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/hooks/useTrafficLimit.ts @@ -0,0 +1,24 @@ +import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; +import { useUiFlag } from 'hooks/useUiFlag'; + +const proPlanIncludedRequests = 53_000_000; +const paygPlanIncludedRequests = proPlanIncludedRequests; + +export const useTrafficLimit = () => { + const { isPro, isEnterprise, uiConfig } = useUiConfig(); + const isEnterprisePaygEnabled = useUiFlag('enterprise-payg'); + + if (isPro()) { + return proPlanIncludedRequests; + } + + if ( + isEnterprisePaygEnabled && + isEnterprise() && + uiConfig.billing === 'pay-as-you-go' + ) { + return paygPlanIncludedRequests; + } + + return 0; +}; diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts index 0f2310a093..5c622eae4f 100644 --- a/frontend/src/interfaces/uiConfig.ts +++ b/frontend/src/interfaces/uiConfig.ts @@ -92,6 +92,7 @@ export type UiFlags = { purchaseAdditionalEnvironments?: boolean; unleashAI?: boolean; releasePlans?: boolean; + 'enterprise-payg'?: boolean; simplifyProjectOverview?: boolean; }; diff --git a/src/lib/types/experimental.ts b/src/lib/types/experimental.ts index f24395ef49..0415c61495 100644 --- a/src/lib/types/experimental.ts +++ b/src/lib/types/experimental.ts @@ -60,6 +60,7 @@ export type IFlagKey = | 'releasePlans' | 'navigationSidebar' | 'productivityReportEmail' + | 'enterprise-payg' | 'simplifyProjectOverview'; export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; @@ -297,6 +298,10 @@ const flags: IFlags = { process.env.UNLEASH_EXPERIMENTAL_PRODUCTIVITY_REPORT_EMAIL, false, ), + 'enterprise-payg': parseEnvVarBoolean( + process.env.UNLEASH_EXPERIMENTAL_ENTERPRISE_PAYG, + false, + ), simplifyProjectOverview: parseEnvVarBoolean( process.env.UNLEASH_EXPERIMENTAL_SIMPLIFY_PROJECT_OVERVIEW, false,