diff --git a/src/App.test.tsx b/src/App.test.tsx index 3b4562b604..e8dc0a48f0 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -9,6 +9,7 @@ import { type Mock, vi } from 'vitest' import config from 'config' import { useLocationParams } from 'services/navigation' +import { Plans } from 'shared/utils/billing' import App from './App' @@ -85,7 +86,7 @@ const user = { service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, diff --git a/src/layouts/BaseLayout/BaseLayout.test.tsx b/src/layouts/BaseLayout/BaseLayout.test.tsx index 9d82c11fc8..94087f587d 100644 --- a/src/layouts/BaseLayout/BaseLayout.test.tsx +++ b/src/layouts/BaseLayout/BaseLayout.test.tsx @@ -10,6 +10,7 @@ import config from 'config' import { useImage } from 'services/image' import { useImpersonate } from 'services/impersonate' import { useInternalUser, useUser } from 'services/user' +import { Plans } from 'shared/utils/billing' import BaseLayout from './BaseLayout' @@ -73,7 +74,7 @@ const mockTrackingMetadata = { service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, diff --git a/src/layouts/BaseLayout/hooks/useUserAccessGate.test.tsx b/src/layouts/BaseLayout/hooks/useUserAccessGate.test.tsx index d5b8002cd5..de6d2b723a 100644 --- a/src/layouts/BaseLayout/hooks/useUserAccessGate.test.tsx +++ b/src/layouts/BaseLayout/hooks/useUserAccessGate.test.tsx @@ -7,6 +7,7 @@ import { MemoryRouter, Route } from 'react-router-dom' import config from 'config' import { User } from 'services/user' +import { Plans } from 'shared/utils/billing' import { useUserAccessGate } from './useUserAccessGate' @@ -73,7 +74,7 @@ const mockTrackingMetadata = { service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, diff --git a/src/layouts/Header/Header.test.tsx b/src/layouts/Header/Header.test.tsx index c1044050e5..2338e878eb 100644 --- a/src/layouts/Header/Header.test.tsx +++ b/src/layouts/Header/Header.test.tsx @@ -9,6 +9,7 @@ import config from 'config' import { useImpersonate } from 'services/impersonate' import { User } from 'services/user' +import { Plans } from 'shared/utils/billing' import Header from './Header' @@ -58,7 +59,7 @@ const mockUser = { service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, diff --git a/src/layouts/Header/components/Navigator/Navigator.test.tsx b/src/layouts/Header/components/Navigator/Navigator.test.tsx index 6225cb2a0c..9c32f7eed7 100644 --- a/src/layouts/Header/components/Navigator/Navigator.test.tsx +++ b/src/layouts/Header/components/Navigator/Navigator.test.tsx @@ -7,6 +7,7 @@ import { useLayoutEffect } from 'react' import { MemoryRouter, Route, useParams } from 'react-router-dom' import { RepoBreadcrumbProvider, useCrumbs } from 'pages/RepoPage/context' +import { Plans } from 'shared/utils/billing' import Navigator from './Navigator' @@ -83,7 +84,7 @@ const mockUser = { service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, diff --git a/src/layouts/Header/components/UserDropdown/UserDropdown.test.tsx b/src/layouts/Header/components/UserDropdown/UserDropdown.test.tsx index 5e491b9116..c444bc3725 100644 --- a/src/layouts/Header/components/UserDropdown/UserDropdown.test.tsx +++ b/src/layouts/Header/components/UserDropdown/UserDropdown.test.tsx @@ -9,6 +9,7 @@ import { type Mock } from 'vitest' import config from 'config' import { useImage } from 'services/image' +import { Plans } from 'shared/utils/billing' import UserDropdown from './UserDropdown' @@ -36,7 +37,7 @@ const mockUser = { service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, diff --git a/src/layouts/Header/components/UserDropdown/UserDropdown.tsx b/src/layouts/Header/components/UserDropdown/UserDropdown.tsx index f942e17e93..7a056b2094 100644 --- a/src/layouts/Header/components/UserDropdown/UserDropdown.tsx +++ b/src/layouts/Header/components/UserDropdown/UserDropdown.tsx @@ -3,13 +3,14 @@ import { useHistory, useParams } from 'react-router-dom' import config from 'config' import { useUser } from 'services/user' +import { Provider } from 'shared/api/helpers' import { providerToName } from 'shared/utils/provider' import Avatar from 'ui/Avatar' import Button from 'ui/Button' import { Dropdown } from 'ui/Dropdown/Dropdown' interface URLParams { - provider: string + provider: Provider } type DropdownItem = { diff --git a/src/mocks/handlers.js b/src/mocks/handlers.js index 3000f86de1..0b553cc001 100644 --- a/src/mocks/handlers.js +++ b/src/mocks/handlers.js @@ -8,6 +8,7 @@ import { flagsSelectHandler, } from 'services/repo/mocks' import { randomUsersHandler } from 'services/users/mocks' +import { Plans } from 'shared/utils/billing' export const handlers = [ repoCoverageHandler, @@ -42,7 +43,7 @@ graphql.query('CurrentUser', (info) => { service: 'github', ownerid: 3456556, serviceId: '87824812', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: true, hasYaml: false, bot: null, diff --git a/src/pages/AccountSettings/AccountSettings.test.jsx b/src/pages/AccountSettings/AccountSettings.test.jsx index a73301f2b5..0801af2921 100644 --- a/src/pages/AccountSettings/AccountSettings.test.jsx +++ b/src/pages/AccountSettings/AccountSettings.test.jsx @@ -7,6 +7,8 @@ import { MemoryRouter, Route } from 'react-router-dom' import config from 'config' +import { Plans } from 'shared/utils/billing' + import AccountSettings from './AccountSettings' vi.mock('config') @@ -29,7 +31,7 @@ const mockPlanData = { billingRate: 'monthly', marketingName: 'Pro Team', monthlyUploadLimit: 250, - value: 'free-plan', + value: Plans.USERS_BASIC, trialStatus: 'NOT_STARTED', trialStartDate: '', trialEndDate: '', @@ -63,7 +65,7 @@ const mockCurrentUser = (username) => ({ service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, @@ -129,14 +131,14 @@ describe('AccountSettings', () => { username = 'codecov', isAdmin = false, hideAccessTab = true, - planValue = 'free-plan', + planValue = Plans.USERS_BASIC, } = { isSelfHosted: false, owner: 'codecov', username: 'codecov', isAdmin: false, hideAccessTab: true, - planValue: 'free-plan', + planValue: Plans.USERS_BASIC, } ) { config.IS_SELF_HOSTED = isSelfHosted @@ -357,7 +359,7 @@ describe('AccountSettings', () => { describe('on okta access route', () => { it('renders okta access tab for enterprise users', async () => { setup({ - planValue: 'users-enterprisem', + planValue: Plans.USERS_ENTERPRISEM, isSelfHosted: false, }) diff --git a/src/pages/AccountSettings/AccountSettingsSideMenu.test.jsx b/src/pages/AccountSettings/AccountSettingsSideMenu.test.jsx index 7b0222f654..6a0a7c1957 100644 --- a/src/pages/AccountSettings/AccountSettingsSideMenu.test.jsx +++ b/src/pages/AccountSettings/AccountSettingsSideMenu.test.jsx @@ -7,6 +7,8 @@ import { MemoryRouter, Route } from 'react-router-dom' import config from 'config' +import { Plans } from 'shared/utils/billing' + import AccountSettingsSideMenu from './AccountSettingsSideMenu' vi.mock('config') @@ -17,7 +19,7 @@ const mockPlanData = { billingRate: 'monthly', marketingName: 'Pro Team', monthlyUploadLimit: 250, - value: 'free-plan', + value: Plans.USERS_BASIC, trialStatus: 'NOT_STARTED', trialStartDate: '', trialEndDate: '', @@ -51,7 +53,7 @@ const mockCurrentUser = (username) => ({ service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, @@ -117,14 +119,14 @@ describe('AccountSettingsSideMenu', () => { owner = 'codecov', isSelfHosted = false, hideAccessTab = false, - planValue = 'free-plan', + planValue = Plans.USERS_BASIC, } = { isAdmin: false, username: 'codecov', isSelfHosted: false, owner: 'codecov', hideAccessTab: false, - planValue: 'free-plan', + planValue: Plans.USERS_BASIC, } ) { config.IS_SELF_HOSTED = isSelfHosted @@ -288,7 +290,7 @@ describe('AccountSettingsSideMenu', () => { describe("okta access is displayed according to the user's plan", () => { it('displays okta access tab if user is on enterprise', async () => { - setup({ isAdmin: true, planValue: 'users-enterprisem' }) + setup({ isAdmin: true, planValue: Plans.USERS_ENTERPRISEM }) render(, { wrapper: wrapper(), @@ -339,7 +341,7 @@ describe('AccountSettingsSideMenu', () => { setup({ isAdmin: true, username: 'cool-new-user', - planValue: 'users-enterprisem', + planValue: Plans.USERS_ENTERPRISEM, }) render(, { @@ -411,7 +413,7 @@ describe('AccountSettingsSideMenu', () => { describe("okta access is displayed according to the user's plan", () => { it('displays okta access tab if user is on enterprise', async () => { - setup({ planValue: 'users-enterprisem' }) + setup({ planValue: Plans.USERS_ENTERPRISEM }) render(, { wrapper: wrapper(), diff --git a/src/pages/AccountSettings/tabs/Access/Access.test.tsx b/src/pages/AccountSettings/tabs/Access/Access.test.tsx index 32f01b0d0c..7877b8621a 100644 --- a/src/pages/AccountSettings/tabs/Access/Access.test.tsx +++ b/src/pages/AccountSettings/tabs/Access/Access.test.tsx @@ -7,6 +7,8 @@ import { setupServer } from 'msw/node' import { Suspense } from 'react' import { MemoryRouter, Route, useLocation } from 'react-router-dom' +import { Plans } from 'shared/utils/billing' + import Access from './Access' window.confirm = vi.fn(() => true) @@ -35,7 +37,7 @@ const mockSignedInUser = { service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, diff --git a/src/pages/AccountSettings/tabs/Admin/Admin.test.jsx b/src/pages/AccountSettings/tabs/Admin/Admin.test.jsx index 818198e0b7..b1f77db610 100644 --- a/src/pages/AccountSettings/tabs/Admin/Admin.test.jsx +++ b/src/pages/AccountSettings/tabs/Admin/Admin.test.jsx @@ -4,6 +4,8 @@ import { graphql, HttpResponse } from 'msw' import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' +import { Plans } from 'shared/utils/billing' + import Admin from './Admin' vi.mock('./DetailsSection', () => ({ default: () => 'DetailsSection' })) @@ -38,7 +40,7 @@ const user = { service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, diff --git a/src/pages/AccountSettings/tabs/Admin/GithubIntegrationSection/GithubIntegrationSection.test.jsx b/src/pages/AccountSettings/tabs/Admin/GithubIntegrationSection/GithubIntegrationSection.test.jsx index d2ab53f07f..664e013bcd 100644 --- a/src/pages/AccountSettings/tabs/Admin/GithubIntegrationSection/GithubIntegrationSection.test.jsx +++ b/src/pages/AccountSettings/tabs/Admin/GithubIntegrationSection/GithubIntegrationSection.test.jsx @@ -6,6 +6,8 @@ import { MemoryRouter, Route } from 'react-router-dom' import config from 'config' +import { Plans } from 'shared/utils/billing' + import GithubIntegrationSection from './GithubIntegrationSection' const server = setupServer() @@ -54,11 +56,11 @@ describe('GithubIntegrationSection', () => { http.get(`/internal/gh/codecov/account-details/`, (info) => { return HttpResponse.json({ plan: { - marketingName: 'users-basic', + marketingName: Plans.USERS_BASIC, baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 5, - value: 'users-inappm', + value: Plans.USERS_INAPPM, }, activatedUserCount: 2, inactiveUserCount: 1, diff --git a/src/pages/DefaultOrgSelector/DefaultOrgSelector.test.jsx b/src/pages/DefaultOrgSelector/DefaultOrgSelector.test.jsx index 27cf674183..f617c2d016 100644 --- a/src/pages/DefaultOrgSelector/DefaultOrgSelector.test.jsx +++ b/src/pages/DefaultOrgSelector/DefaultOrgSelector.test.jsx @@ -10,6 +10,8 @@ import config from 'config' import { SentryBugReporter } from 'sentry' +import { Plans } from 'shared/utils/billing' + import DefaultOrgSelector from './DefaultOrgSelector' const mocks = vi.hoisted(() => ({ @@ -38,7 +40,7 @@ const mockTrialData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: 'ONGOING', trialStartDate: '2023-01-01T08:55:25', trialEndDate: '2023-01-10T08:55:25', @@ -72,7 +74,7 @@ const mockUserData = { service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, @@ -116,7 +118,7 @@ const mockBusinessUserData = { service: 'github', ownerid: 123, serviceId: '123', - plan: 'users-basic', + plan: Plans.USERS_BASIC, staff: false, hasYaml: false, bot: null, @@ -177,7 +179,7 @@ describe('DefaultOrgSelector', () => { useUserData, isValidUser = true, trialStatus = 'NOT_STARTED', - value = 'users-basic', + value = Plans.USERS_BASIC, privateRepos = true, } = {}) { const mockMutationVariables = vi.fn() @@ -218,7 +220,7 @@ describe('DefaultOrgSelector', () => { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, }, }, }, @@ -822,7 +824,7 @@ describe('DefaultOrgSelector', () => { it('does not fire trial mutation', async () => { const { user, mockTrialMutationVariables } = setup({ useUserData: mockUserData, - value: 'users-free', + value: Plans.USERS_FREE, myOrganizationsData: { me: { myOrganizations: { @@ -1063,7 +1065,7 @@ describe('DefaultOrgSelector', () => { }, }, }, - value: 'users-basic', + value: Plans.USERS_BASIC, }) render(, { wrapper: wrapper() }) @@ -1126,7 +1128,7 @@ describe('DefaultOrgSelector', () => { }, }, }, - value: 'users-basic', + value: Plans.USERS_BASIC, privateRepos: false, }) diff --git a/src/pages/DefaultOrgSelector/GitHubHelpBanner/GitHubHelpBanner.tsx b/src/pages/DefaultOrgSelector/GitHubHelpBanner/GitHubHelpBanner.tsx index 748bb3a4d5..159c0b30d0 100644 --- a/src/pages/DefaultOrgSelector/GitHubHelpBanner/GitHubHelpBanner.tsx +++ b/src/pages/DefaultOrgSelector/GitHubHelpBanner/GitHubHelpBanner.tsx @@ -2,6 +2,7 @@ import { useState } from 'react' import { useParams } from 'react-router-dom' import { useResyncUser } from 'services/user' +import { Provider } from 'shared/api/helpers' import AppInstallModal from 'shared/AppInstallModal' import { providerToName } from 'shared/utils' import A from 'ui/A' @@ -42,7 +43,7 @@ function ResyncButton() { function GitHubHelpBanner() { const [showModal, setShowModal] = useState(false) - const { provider } = useParams<{ provider: string }>() + const { provider } = useParams<{ provider: Provider }>() if (providerToName(provider) !== 'Github') return null return ( diff --git a/src/pages/MembersPage/MembersActivation/Activation/Activation.test.jsx b/src/pages/MembersPage/MembersActivation/Activation/Activation.test.jsx index 31c3edd4a1..96a56eae54 100644 --- a/src/pages/MembersPage/MembersActivation/Activation/Activation.test.jsx +++ b/src/pages/MembersPage/MembersActivation/Activation/Activation.test.jsx @@ -5,6 +5,7 @@ import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' import { TrialStatuses } from 'services/account' +import { Plans } from 'shared/utils/billing' import Activation from './Activation' @@ -18,7 +19,7 @@ const mockedAccountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 9, - value: 'users-basic', + value: Plans.USERS_BASIC, }, activatedUserCount: 5, inactiveUserCount: 1, @@ -30,7 +31,7 @@ const mockPlanData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/MembersPage/MembersActivation/Activation/ChangePlanLink/ChangePlanLink.test.jsx b/src/pages/MembersPage/MembersActivation/Activation/ChangePlanLink/ChangePlanLink.test.jsx index 71a0a235d7..e95a83178d 100644 --- a/src/pages/MembersPage/MembersActivation/Activation/ChangePlanLink/ChangePlanLink.test.jsx +++ b/src/pages/MembersPage/MembersActivation/Activation/ChangePlanLink/ChangePlanLink.test.jsx @@ -3,6 +3,8 @@ import { MemoryRouter, Route } from 'react-router-dom' import config from 'config' +import { Plans } from 'shared/utils/billing' + import ChangePlanLink from './ChangePlanLink' const wrapper = @@ -18,7 +20,7 @@ describe('Members ChangePlanLink', () => { it('Renders change plan link', async () => { const mockedAccountDetailsNonEnterprise = { plan: { - value: 'users-basic', + value: Plans.USERS_BASIC, }, subscriptionDetail: { collectionMethod: 'paid', @@ -44,7 +46,7 @@ describe('Members ChangePlanLink', () => { it('Does not render change plan link', async () => { const mockedAccountDetailsNonEnterprise = { plan: { - value: 'users-basic', + value: Plans.USERS_BASIC, }, subscriptionDetail: { collectionMethod: 'paid', @@ -65,7 +67,7 @@ describe('Members ChangePlanLink', () => { it('Does not render change plan link', async () => { const mockedAccountDetailsEnterprise = { plan: { - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISE, }, subscriptionDetail: { collectionMethod: 'paid', @@ -86,7 +88,7 @@ describe('Members ChangePlanLink', () => { it('Does not render change plan link', async () => { const mockedAccountDetailsInvoiceUser = { plan: { - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, }, subscriptionDetail: { collectionMethod: 'send_invoice', diff --git a/src/pages/MembersPage/MembersActivation/MembersActivation.test.jsx b/src/pages/MembersPage/MembersActivation/MembersActivation.test.jsx index c900dd6d38..55815db767 100644 --- a/src/pages/MembersPage/MembersActivation/MembersActivation.test.jsx +++ b/src/pages/MembersPage/MembersActivation/MembersActivation.test.jsx @@ -20,7 +20,7 @@ const mockedAccountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 9, - value: 'users-basic', + value: Plans.USERS_BASIC, }, activatedUserCount: 5, inactiveUserCount: 1, @@ -32,7 +32,7 @@ const mockPlanData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/OwnerPage/HeaderBanners/ExceededUploadsAlert/ExceededUploadsAlert.test.jsx b/src/pages/OwnerPage/HeaderBanners/ExceededUploadsAlert/ExceededUploadsAlert.test.jsx index 5d8e346d27..6b7ed7b4ec 100644 --- a/src/pages/OwnerPage/HeaderBanners/ExceededUploadsAlert/ExceededUploadsAlert.test.jsx +++ b/src/pages/OwnerPage/HeaderBanners/ExceededUploadsAlert/ExceededUploadsAlert.test.jsx @@ -5,6 +5,7 @@ import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' import { TrialStatuses } from 'services/account' +import { Plans } from 'shared/utils/billing' import ExceededUploadsAlert from './ExceededUploadsAlert' @@ -28,7 +29,7 @@ const mockPlanDataResponse = { billingRate: 'monthly', marketingName: 'some-name', monthlyUploadLimit: 123, - value: 'test-plan', + value: Plans.USERS_PR_INAPPM, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/OwnerPage/HeaderBanners/HeaderBanners.test.jsx b/src/pages/OwnerPage/HeaderBanners/HeaderBanners.test.jsx index 0363154351..152e2a6b5a 100644 --- a/src/pages/OwnerPage/HeaderBanners/HeaderBanners.test.jsx +++ b/src/pages/OwnerPage/HeaderBanners/HeaderBanners.test.jsx @@ -7,6 +7,7 @@ import { MemoryRouter, Route } from 'react-router-dom' import config from 'config' import { TrialStatuses } from 'services/account' +import { Plans } from 'shared/utils/billing' import HeaderBanners from './HeaderBanners' @@ -31,7 +32,7 @@ const mockPlanDataResponse = { billingRate: 'monthly', marketingName: 'Pro Team', monthlyUploadLimit: 250, - value: 'test-plan', + value: Plans.USERS_PR_INAPPM, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/OwnerPage/HeaderBanners/ReachingUploadLimitAlert/ReachingUploadLimitAlert.test.jsx b/src/pages/OwnerPage/HeaderBanners/ReachingUploadLimitAlert/ReachingUploadLimitAlert.test.jsx index ffec60e9dc..996655ce82 100644 --- a/src/pages/OwnerPage/HeaderBanners/ReachingUploadLimitAlert/ReachingUploadLimitAlert.test.jsx +++ b/src/pages/OwnerPage/HeaderBanners/ReachingUploadLimitAlert/ReachingUploadLimitAlert.test.jsx @@ -5,6 +5,7 @@ import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' import { TrialStatuses } from 'services/account' +import { Plans } from 'shared/utils/billing' import ReachingUploadLimitAlert from './ReachingUploadLimitAlert' @@ -28,7 +29,7 @@ const mockPlanDataResponse = { billingRate: 'monthly', marketingName: 'Pro Team', monthlyUploadLimit: 341, - value: 'test-plan', + value: Plans.USERS_PR_INAPPM, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/OwnerPage/Tabs/TrialReminder/TrialReminder.test.tsx b/src/pages/OwnerPage/Tabs/TrialReminder/TrialReminder.test.tsx index f3b7a84b51..c88f16bc64 100644 --- a/src/pages/OwnerPage/Tabs/TrialReminder/TrialReminder.test.tsx +++ b/src/pages/OwnerPage/Tabs/TrialReminder/TrialReminder.test.tsx @@ -31,7 +31,7 @@ const mockResponse = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/PlanPage/subRoutes/CancelPlanPage/CancelPlanPage.test.tsx b/src/pages/PlanPage/subRoutes/CancelPlanPage/CancelPlanPage.test.tsx index 2eb6de6387..ddc19032f4 100644 --- a/src/pages/PlanPage/subRoutes/CancelPlanPage/CancelPlanPage.test.tsx +++ b/src/pages/PlanPage/subRoutes/CancelPlanPage/CancelPlanPage.test.tsx @@ -23,7 +23,7 @@ const teamPlans = [ billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, }, { baseUnitPrice: 5, @@ -31,14 +31,14 @@ const teamPlans = [ billingRate: 'yearly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, }, ] const mockAvailablePlans = ({ hasTeamPlans }: { hasTeamPlans: boolean }) => [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -50,7 +50,7 @@ const mockAvailablePlans = ({ hasTeamPlans }: { hasTeamPlans: boolean }) => [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -70,7 +70,7 @@ const mockPlanData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/DowngradePlan/DowngradePlan.test.jsx b/src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/DowngradePlan/DowngradePlan.test.jsx index b02661648d..4bd0daafae 100644 --- a/src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/DowngradePlan/DowngradePlan.test.jsx +++ b/src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/DowngradePlan/DowngradePlan.test.jsx @@ -5,6 +5,8 @@ import { setupServer } from 'msw/node' import { Suspense } from 'react' import { MemoryRouter, Route } from 'react-router-dom' +import { Plans } from 'shared/utils/billing' + import DowngradePlan from './DowngradePlan' const mockAccountDetails = { @@ -13,7 +15,7 @@ const mockAccountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 5, - value: 'users-inappm', + value: Plans.USERS_PR_INAPPM, }, activatedUserCount: 2, inactiveUserCount: 1, diff --git a/src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.test.tsx b/src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.test.tsx index 0051d09e57..b04eea11dd 100644 --- a/src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.test.tsx +++ b/src/pages/PlanPage/subRoutes/CancelPlanPage/subRoutes/TeamPlanSpecialOffer/TeamPlanCard/TeamPlanCard.test.tsx @@ -4,6 +4,8 @@ import { graphql, HttpResponse } from 'msw' import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' +import { Plans } from 'shared/utils/billing' + import TeamPlanCard from './TeamPlanCard' vi.mock('shared/plan/BenefitList', () => ({ default: () => 'BenefitsList' })) @@ -11,7 +13,7 @@ vi.mock('shared/plan/BenefitList', () => ({ default: () => 'BenefitsList' })) const mockAvailablePlans = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -23,7 +25,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -36,7 +38,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -49,7 +51,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -62,7 +64,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -79,7 +81,7 @@ const mockAvailablePlans = [ billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, }, { baseUnitPrice: 5, @@ -87,7 +89,7 @@ const mockAvailablePlans = [ billingRate: 'yearly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, }, ] diff --git a/src/pages/PlanPage/subRoutes/CancelPlanPage/useProPlanMonth.js b/src/pages/PlanPage/subRoutes/CancelPlanPage/useProPlanMonth.js index 1db00fe6df..94d703e9d8 100644 --- a/src/pages/PlanPage/subRoutes/CancelPlanPage/useProPlanMonth.js +++ b/src/pages/PlanPage/subRoutes/CancelPlanPage/useProPlanMonth.js @@ -1,4 +1,5 @@ import { useFlags } from 'shared/featureFlags' +import { Plans } from 'shared/utils/billing' export function useProPlanMonth({ plans }) { const { enterpriseCloudPlanSupport } = useFlags({ @@ -8,9 +9,10 @@ export function useProPlanMonth({ plans }) { const proPlanMonth = enterpriseCloudPlanSupport ? plans.find( (plan) => - plan.value === 'users-pr-inappm' || plan.value === 'users-enterprisem' + plan.value === Plans.USERS_PR_INAPPM || + plan.value === Plans.USERS_ENTERPRISEM ) - : plans.find((plan) => plan.value === 'users-pr-inappm') + : plans.find((plan) => plan.value === Plans.USERS_PR_INAPPM) return { proPlanMonth, diff --git a/src/pages/PlanPage/subRoutes/CancelPlanPage/useProPlanMonth.test.js b/src/pages/PlanPage/subRoutes/CancelPlanPage/useProPlanMonth.test.js index 5853b1d3d4..76a834c920 100644 --- a/src/pages/PlanPage/subRoutes/CancelPlanPage/useProPlanMonth.test.js +++ b/src/pages/PlanPage/subRoutes/CancelPlanPage/useProPlanMonth.test.js @@ -1,5 +1,7 @@ import { renderHook } from '@testing-library/react' +import { Plans } from 'shared/utils/billing' + import { useProPlanMonth } from './useProPlanMonth' const mocks = vi.hoisted(() => ({ @@ -26,7 +28,7 @@ describe('useProPlanMonth', () => { const plans = [ { marketingName: 'Basic', - value: 'users-free', + value: Plans.USERS_FREE, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -37,7 +39,7 @@ describe('useProPlanMonth', () => { }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -55,7 +57,7 @@ describe('useProPlanMonth', () => { expect(result.current).toEqual({ proPlanMonth: { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -71,7 +73,7 @@ describe('useProPlanMonth', () => { const plans = [ { marketingName: 'Basic', - value: 'users-free', + value: Plans.USERS_FREE, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -82,7 +84,7 @@ describe('useProPlanMonth', () => { }, { marketingName: 'Pro Team', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -101,7 +103,7 @@ describe('useProPlanMonth', () => { expect(result.current).toEqual({ proPlanMonth: { marketingName: 'Pro Team', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -128,7 +130,7 @@ describe('useProPlanMonth', () => { expect(result.current).toEqual({ proPlanMonth: { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -147,7 +149,7 @@ function getPlans() { return [ { marketingName: 'Basic', - value: 'users-free', + value: Plans.USERS_FREE, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -158,7 +160,7 @@ function getPlans() { }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -170,7 +172,7 @@ function getPlans() { }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -182,7 +184,7 @@ function getPlans() { }, { marketingName: 'Pro Team', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISE, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -194,7 +196,7 @@ function getPlans() { }, { marketingName: 'Pro Team', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/BillingDetails.test.tsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/BillingDetails.test.tsx index a73f39b7b5..bdfa6fd569 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/BillingDetails.test.tsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/BillingDetails.test.tsx @@ -4,6 +4,8 @@ import { http, HttpResponse } from 'msw' import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' +import { Plans } from 'shared/utils/billing' + import BillingDetails from './BillingDetails' vi.mock('./PaymentCard/PaymentCard', () => ({ default: () => 'Payment Card' })) @@ -46,7 +48,7 @@ const mockSubscription = { }, }, plan: { - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, }, currentPeriodEnd: 1606851492, cancelAtPeriodEnd: false, diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/PaymentCard.test.jsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/PaymentCard.test.jsx index 7bc34837aa..cb9ca3cfe8 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/PaymentCard.test.jsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/PaymentCard.test.jsx @@ -2,6 +2,7 @@ import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { ThemeContextProvider } from 'shared/ThemeContext' +import { Plans } from 'shared/utils/billing' import PaymentCard from './PaymentCard' @@ -27,7 +28,7 @@ const subscriptionDetail = { }, }, plan: { - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, }, currentPeriodEnd: 1606851492, cancelAtPeriodEnd: false, diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/useEnterpriseCloudPlanSupport.js b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/useEnterpriseCloudPlanSupport.js index 753ee3e407..ec86aba31a 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/useEnterpriseCloudPlanSupport.js +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/useEnterpriseCloudPlanSupport.js @@ -1,11 +1,12 @@ import { useFlags } from 'shared/featureFlags' +import { Plans } from 'shared/utils/billing' export function useEnterpriseCloudPlanSupport({ plans }) { const { enterpriseCloudPlanSupport } = useFlags({ enterpriseCloudPlanSupport: true, }) - const enterprisePlans = ['users-enterprisem', 'users-enterprisey'] + const enterprisePlans = [Plans.USERS_ENTERPRISEM, Plans.USERS_ENTERPRISEY] if (enterpriseCloudPlanSupport) { plans.push(...enterprisePlans) diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentOrgPlan.test.tsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentOrgPlan.test.tsx index 2eabbea9a3..ab478617f9 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentOrgPlan.test.tsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentOrgPlan.test.tsx @@ -8,6 +8,7 @@ import { z } from 'zod' import { PlanUpdatedPlanNotificationContext } from 'pages/PlanPage/context' import { AccountDetailsSchema } from 'services/account' +import { Plans } from 'shared/utils/billing' import { AlertOptions, type AlertOptionsType } from 'ui/Alert' import CurrentOrgPlan from './CurrentOrgPlan' @@ -30,7 +31,7 @@ const mockedAccountDetails = { planProvider: 'github', rootOrganization: {}, plan: { - value: 'users-free', + value: Plans.USERS_FREE, }, usesInvoice: false, } as z.infer @@ -173,7 +174,7 @@ describe('CurrentOrgPlan', () => { billingRate: 'monthly', marketingName: 'Pro', quantity: 39, - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, }, } as z.infer, }) @@ -191,7 +192,7 @@ describe('CurrentOrgPlan', () => { billingRate: 'monthly', marketingName: 'Pro', quantity: 39, - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, }, scheduleDetail: { scheduledPhase: { @@ -218,7 +219,7 @@ describe('CurrentOrgPlan', () => { billingRate: 'monthly', marketingName: 'Pro', quantity: 39, - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, }, } as z.infer, }) @@ -241,7 +242,7 @@ describe('CurrentOrgPlan', () => { billingRate: 'monthly', marketingName: 'Pro', quantity: 39, - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, }, subscriptionDetail: { cancelAtPeriodEnd: true, @@ -266,7 +267,7 @@ describe('CurrentOrgPlan', () => { planProvider: 'gitlab', rootOrganization: null, plan: { - value: 'users-free', + value: Plans.USERS_FREE, baseUnitPrice: 12, benefits: ['a', 'b'], billingRate: '1', @@ -302,7 +303,7 @@ describe('CurrentOrgPlan', () => { planProvider: 'github', rootOrganization: {}, plan: { - value: 'users-free', + value: Plans.USERS_FREE, baseUnitPrice: 12, benefits: ['a', 'b'], billingRate: '1', diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/CurrentPlanCard.test.tsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/CurrentPlanCard.test.tsx index 5b5fec9828..84b944ab73 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/CurrentPlanCard.test.tsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/CurrentPlanCard.test.tsx @@ -5,6 +5,8 @@ import { setupServer } from 'msw/node' import React from 'react' import { MemoryRouter, Route } from 'react-router-dom' +import { PlanName, Plans } from 'shared/utils/billing' + import CurrentPlanCard from './CurrentPlanCard' vi.mock('./FreePlanCard', () => ({ default: () => 'Free plan card' })) @@ -19,7 +21,7 @@ const proPlanDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 5, - value: 'users-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: null, }, } @@ -27,7 +29,7 @@ const proPlanDetails = { const freePlanDetails = { plan: { marketingName: 'Basic', - value: 'users-free', + value: Plans.USERS_FREE, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -41,7 +43,7 @@ const freePlanDetails = { const enterprisePlan = { plan: { marketingName: 'Enterprise', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -55,7 +57,7 @@ const enterprisePlan = { const usesInvoiceTeamPlan = { plan: { marketingName: 'blah', - value: 'users-teamm', + value: Plans.USERS_TEAMM, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -74,10 +76,20 @@ const trialPlanDetails = { billingRate: null, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 5, - value: 'users-trial', + value: Plans.USERS_TRIAL, }, } +interface TestPlan { + plan: { + marketingName: string + value: PlanName + billingRate: null + baseUnitPrice: number + benefits: string[] + } +} + const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } }, }) @@ -100,7 +112,7 @@ afterEach(() => { afterAll(() => server.close()) describe('CurrentPlanCard', () => { - function setup(planDetails = freePlanDetails) { + function setup(planDetails: TestPlan = freePlanDetails) { server.use( http.get('/internal/bb/critical-role/account-details/', (http) => { return HttpResponse.json(planDetails) diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/EnterprisePlanCard/EnterprisePlanCard.test.jsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/EnterprisePlanCard/EnterprisePlanCard.test.jsx index 45f255980f..228d890ede 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/EnterprisePlanCard/EnterprisePlanCard.test.jsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/EnterprisePlanCard/EnterprisePlanCard.test.jsx @@ -2,11 +2,13 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { render, screen } from '@testing-library/react' import { MemoryRouter, Route } from 'react-router-dom' +import { Plans } from 'shared/utils/billing' + import EnterprisePlanCard from './EnterprisePlanCard' const enterprisePlan = { marketingName: 'Enterprise', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: null, baseUnitPrice: 0, benefits: [ diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/FreePlanCard.test.jsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/FreePlanCard.test.jsx index 636ce6ce92..fdd561b54d 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/FreePlanCard.test.jsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/FreePlanCard.test.jsx @@ -6,6 +6,7 @@ import { Suspense } from 'react' import { MemoryRouter, Route } from 'react-router-dom' import { TrialStatuses } from 'services/account' +import { Plans } from 'shared/utils/billing' import FreePlanCard from './FreePlanCard' @@ -14,7 +15,7 @@ vi.mock('./PlanUpgradeTeam', () => ({ default: () => 'PlanUpgradeTeam' })) const allPlans = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -26,7 +27,7 @@ const allPlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -39,7 +40,7 @@ const allPlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -52,7 +53,7 @@ const allPlans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -65,7 +66,7 @@ const allPlans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -82,7 +83,7 @@ const allPlans = [ billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, }, { baseUnitPrice: 5, @@ -90,14 +91,14 @@ const allPlans = [ billingRate: 'yearly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, }, ] const sentryPlans = [ { marketingName: 'Sentry', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: null, baseUnitPrice: 0, benefits: ['Includes 5 seats', 'Unlimited public repositories'], @@ -105,7 +106,7 @@ const sentryPlans = [ }, { marketingName: 'Sentry', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: null, baseUnitPrice: 10, benefits: ['Includes 5 seats', 'Unlimited private repositories'], @@ -115,7 +116,7 @@ const sentryPlans = [ const freePlan = { marketingName: 'Free', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: ['Up to 1 user', '250 free uploads'], @@ -134,7 +135,7 @@ const mockPlanData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', @@ -150,7 +151,7 @@ const mockPreTrialPlanInfo = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, } const server = setupServer() @@ -192,7 +193,7 @@ describe('FreePlanCard', () => { }, plans = allPlans, trialStatus = TrialStatuses.CANNOT_TRIAL, - planValue = 'users-basic', + planValue = Plans.USERS_BASIC, planUserCount = 1, } = { owner: { @@ -201,7 +202,7 @@ describe('FreePlanCard', () => { numberOfUploads: 10, }, trialStatus: TrialStatuses.CANNOT_TRIAL, - planValue: 'users-basic', + planValue: Plans.USERS_BASIC, plans: allPlans, planUserCount: 1, } diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradePro/PlanUpgradePro.test.jsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradePro/PlanUpgradePro.test.jsx index 63990601cc..fcbf3e7978 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradePro/PlanUpgradePro.test.jsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradePro/PlanUpgradePro.test.jsx @@ -3,6 +3,8 @@ import { render, screen } from '@testing-library/react' import { Suspense } from 'react' import { MemoryRouter, Route } from 'react-router-dom' +import { Plans } from 'shared/utils/billing' + import PlanUpgradePro from './PlanUpgradePro' vi.mock('../ProPlanSubheading', () => ({ default: () => 'Pro Subheading' })) @@ -14,7 +16,7 @@ vi.mock('shared/plan/BenefitList', () => ({ default: () => 'BenefitsList' })) const plansWithoutSentryOptions = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -26,7 +28,7 @@ const plansWithoutSentryOptions = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 789, benefits: [ @@ -39,7 +41,7 @@ const plansWithoutSentryOptions = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 456, benefits: [ @@ -55,7 +57,7 @@ const plansWithoutSentryOptions = [ const plansWithSentryOptions = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -67,7 +69,7 @@ const plansWithSentryOptions = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -80,7 +82,7 @@ const plansWithSentryOptions = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -93,7 +95,7 @@ const plansWithSentryOptions = [ }, { marketingName: 'Sentry', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: null, baseUnitPrice: 0, benefits: ['Includes 5 seats', 'Unlimited public repositories'], @@ -101,7 +103,7 @@ const plansWithSentryOptions = [ }, { marketingName: 'Sentry', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: null, baseUnitPrice: 123, benefits: ['Includes 5 seats', 'Unlimited private repositories'], diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradeTeam/PlanUpgradeTeam.test.jsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradeTeam/PlanUpgradeTeam.test.jsx index 8ec5d2d51c..2bb1aeeebc 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradeTeam/PlanUpgradeTeam.test.jsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/PlanUpgradeTeam/PlanUpgradeTeam.test.jsx @@ -6,6 +6,7 @@ import { Suspense } from 'react' import { MemoryRouter, Route } from 'react-router-dom' import { TrialStatuses } from 'services/account' +import { Plans } from 'shared/utils/billing' import PlanUpgradeTeam from './PlanUpgradeTeam' @@ -17,7 +18,7 @@ const mockPlanBasic = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', @@ -33,7 +34,7 @@ const mockPlanPro = { billingRate: 'monthly', marketingName: 'Pro', monthlyUploadLimit: null, - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, trialStatus: TrialStatuses.CANNOT_TRIAL, trialStartDate: '', trialEndDate: '', @@ -49,7 +50,7 @@ const mockPlanTrialing = { billingRate: 'monthly', marketingName: 'Trial', monthlyUploadLimit: null, - value: 'users-trial', + value: Plans.USERS_TRIAL, trialStatus: TrialStatuses.ONGOING, trialStartDate: '2023-01-01T08:55:25', trialEndDate: '2023-01-10T08:55:25', @@ -62,7 +63,7 @@ const mockPlanTrialing = { const mockAvailablePlans = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -74,7 +75,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -87,7 +88,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -100,7 +101,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -113,7 +114,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -130,7 +131,7 @@ const mockAvailablePlans = [ billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, }, { baseUnitPrice: 5, @@ -138,7 +139,7 @@ const mockAvailablePlans = [ billingRate: 'yearly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, }, ] @@ -148,7 +149,7 @@ const mockPreTrialPlanInfo = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, } const server = setupServer() diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/ProPlanSubheading/ProPlanSubheading.test.tsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/ProPlanSubheading/ProPlanSubheading.test.tsx index d1a307da04..6e0a61809f 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/ProPlanSubheading/ProPlanSubheading.test.tsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/FreePlanCard/ProPlanSubheading/ProPlanSubheading.test.tsx @@ -5,6 +5,7 @@ import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' import { TrialStatuses } from 'services/account' +import { Plans } from 'shared/utils/billing' import ProPlanSubheading from './ProPlanSubheading' @@ -14,7 +15,7 @@ const mockResponse = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', @@ -59,7 +60,7 @@ interface SetupArgs { describe('ProPlanSubheading', () => { function setup({ trialStatus = TrialStatuses.NOT_STARTED, - planValue = 'users-basic', + planValue = Plans.USERS_BASIC, hasPrivateRepos = true, }: SetupArgs) { server.use( diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/PaidPlanCard/PaidPlanCard.test.tsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/PaidPlanCard/PaidPlanCard.test.tsx index 6f14d8df74..2768fa17f6 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/PaidPlanCard/PaidPlanCard.test.tsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/PaidPlanCard/PaidPlanCard.test.tsx @@ -5,6 +5,7 @@ import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' import { Plan, PretrialPlan, TrialStatuses } from 'services/account' +import { Plans } from 'shared/utils/billing' import PaidPlanCard from './PaidPlanCard' @@ -23,7 +24,7 @@ vi.mock('shared/plan/ScheduledPlanDetails', () => ({ const mockProPlan = { marketingName: 'Pro', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 0, benefits: ['Unlimited public repositories', 'Unlimited private repositories'], @@ -39,7 +40,7 @@ const mockProPlan = { const mockTeamPlan = { marketingName: 'Team', - value: 'users-teamm', + value: Plans.USERS_TEAMM, billingRate: 'monthly', baseUnitPrice: 123, benefits: ['Team benefits', 'Unlimited private repositories'], diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/shared/ActionsBilling/ActionsBilling.test.jsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/shared/ActionsBilling/ActionsBilling.test.jsx index c431ee064a..350db0bb1d 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/shared/ActionsBilling/ActionsBilling.test.jsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/CurrentPlanCard/shared/ActionsBilling/ActionsBilling.test.jsx @@ -6,6 +6,7 @@ import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' import { TrialStatuses } from 'services/account' +import { Plans } from 'shared/utils/billing' import ActionsBilling from './ActionsBilling' @@ -24,7 +25,7 @@ vi.mock('shared/useRedirect', async () => { const allPlans = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -36,7 +37,7 @@ const allPlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -49,7 +50,7 @@ const allPlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -62,7 +63,7 @@ const allPlans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -75,7 +76,7 @@ const allPlans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -94,7 +95,7 @@ const sentryPlans = [ baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], monthlyUploadLimit: null, - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', }, ] @@ -105,7 +106,7 @@ const mockedFreeAccountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 9, - value: 'users-basic', + value: Plans.USERS_BASIC, }, activatedUserCount: 5, inactiveUserCount: 1, @@ -117,7 +118,7 @@ const mockedProAccountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 9, - value: 'users-basic', + value: Plans.USERS_BASIC, }, activatedUserCount: 5, inactiveUserCount: 1, @@ -129,7 +130,7 @@ const sentryMockedAccountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 9, - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, }, activatedUserCount: 5, inactiveUserCount: 1, @@ -141,7 +142,7 @@ const mockTrialAccountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 9, - value: 'users-trial', + value: Plans.USERS_TRIAL, }, activatedUserCount: 5, inactiveUserCount: 1, @@ -154,7 +155,7 @@ const mockTrialData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: 'ONGOING', trialStartDate: '2023-01-01T08:55:25', trialEndDate: '2023-01-10T08:55:25', diff --git a/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/InvoiceDetail.test.tsx b/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/InvoiceDetail.test.tsx index 8161747c01..24f1b30d04 100644 --- a/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/InvoiceDetail.test.tsx +++ b/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/InvoiceDetail.test.tsx @@ -1,8 +1,9 @@ import { render, screen, waitFor } from '@testing-library/react' import { MemoryRouter } from 'react-router-dom' -import InvoiceDetail from './InvoiceDetail' +import { Plans } from 'shared/utils/billing' +import InvoiceDetail from './InvoiceDetail' const mocks = vi.hoisted(() => ({ useAccountDetails: vi.fn(), useInvoice: vi.fn(), @@ -47,7 +48,7 @@ const invoice = { amount: -9449, currency: 'usd', period: { end: 1610473200, start: 1609298708 }, - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, quantity: 19, }, { @@ -55,7 +56,7 @@ const invoice = { amount: 72000, currency: 'usd', period: { end: 1640834708, start: 1609298708 }, - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, quantity: 6, }, { @@ -63,7 +64,7 @@ const invoice = { amount: 72000, currency: 'usd', period: { end: null, start: null }, - value: 'same period doesnt render date', + value: null, quantity: 1, }, ], diff --git a/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceFooter.test.jsx b/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceFooter.test.jsx index f78682a5b8..826f1a6f48 100644 --- a/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceFooter.test.jsx +++ b/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceFooter.test.jsx @@ -1,6 +1,8 @@ import { render, screen } from '@testing-library/react' import { MemoryRouter, Route, Switch } from 'react-router-dom' +import { Plans } from 'shared/utils/billing' + import InvoiceFooter from './InvoiceFooter' const invoice = { @@ -26,7 +28,7 @@ const invoice = { amount: -9449, currency: 'usd', period: { end: 1610473200, start: 1609298708 }, - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, quantity: 19, }, { @@ -34,7 +36,7 @@ const invoice = { amount: 72000, currency: 'usd', period: { end: 1640834708, start: 1609298708 }, - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, quantity: 6, }, { @@ -42,7 +44,7 @@ const invoice = { amount: 72000, currency: 'usd', period: { end: null, start: null }, - value: 'same period doesnt render date', + value: null, quantity: 1, }, ], diff --git a/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceHeader.test.tsx b/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceHeader.test.tsx index ecab60be71..83a15c1f7a 100644 --- a/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceHeader.test.tsx +++ b/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceHeader.test.tsx @@ -3,6 +3,7 @@ import { MemoryRouter, Route, Switch } from 'react-router-dom' import { z } from 'zod' import { InvoiceSchema } from 'services/account' +import { Plans } from 'shared/utils/billing' import InvoiceHeader from './InvoiceHeader' @@ -45,7 +46,7 @@ const mockInvoice = ({ status = 'paid' } = {}) => { amount: -9449, currency: 'usd', period: { end: 1610473200, start: 1609298708 }, - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, quantity: 19, }, { @@ -53,7 +54,7 @@ const mockInvoice = ({ status = 'paid' } = {}) => { amount: 72000, currency: 'usd', period: { end: 1640834708, start: 1609298708 }, - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, quantity: 6, }, { @@ -62,7 +63,7 @@ const mockInvoice = ({ status = 'paid' } = {}) => { currency: 'usd', // @ts-expect-error period: { end: null, start: null }, - value: 'same period doesnt render date', + value: null, quantity: 1, }, ], diff --git a/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceItems.test.jsx b/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceItems.test.jsx index 726ad9b76c..1d6cd7242c 100644 --- a/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceItems.test.jsx +++ b/src/pages/PlanPage/subRoutes/InvoiceDetailsPage/sections/InvoiceItems.test.jsx @@ -1,6 +1,8 @@ import { render, screen } from '@testing-library/react' import { MemoryRouter, Route, Switch } from 'react-router-dom' +import { Plans } from 'shared/utils/billing' + import InvoiceItems from './InvoiceItems' const invoice = { @@ -26,7 +28,7 @@ const invoice = { amount: -9449, currency: 'usd', period: { end: 1610473200, start: 1609298708 }, - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, quantity: 19, }, { @@ -34,7 +36,7 @@ const invoice = { amount: 72000, currency: 'usd', period: { end: 1640834708, start: 1609298708 }, - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, quantity: 6, }, { @@ -42,7 +44,7 @@ const invoice = { amount: 72000, currency: 'usd', period: { end: null, start: null }, - value: 'same period doesnt render date', + value: null, quantity: 1, }, ], diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/PlanDetailsControls/PlanDetailsControls.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/PlanDetailsControls/PlanDetailsControls.test.tsx index 31dfa313fa..c72df24819 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/PlanDetailsControls/PlanDetailsControls.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/PlanDetailsControls/PlanDetailsControls.test.tsx @@ -12,7 +12,7 @@ import PlanDetailsControls from './PlanDetailsControls' const proPlanMonth = { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -26,7 +26,7 @@ const proPlanMonth = { const proPlanYear = { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -40,7 +40,7 @@ const proPlanYear = { const sentryPlanMonth = { marketingName: 'Sentry Pro Team', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -54,7 +54,7 @@ const sentryPlanMonth = { const sentryPlanYear = { marketingName: 'Sentry Pro Team', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -72,7 +72,7 @@ const teamPlanMonth = { billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, } const teamPlanYear = { @@ -81,7 +81,7 @@ const teamPlanYear = { billingRate: 'annually', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, } const server = setupServer() diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/PlanDetailsControls/PlanDetailsControls.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/PlanDetailsControls/PlanDetailsControls.tsx index bfacbf3b7f..74856449a0 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/PlanDetailsControls/PlanDetailsControls.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/PlanDetailsControls/PlanDetailsControls.tsx @@ -1,18 +1,19 @@ import { useState } from 'react' import { useParams } from 'react-router-dom' -import { IndividualPlan, useAvailablePlans } from 'services/account' +import { useAvailablePlans } from 'services/account' import { findProPlans, findSentryPlans, findTeamPlans, + Plan, } from 'shared/utils/billing' import { TEAM_PLAN_MAX_ACTIVE_USERS } from 'shared/utils/upgradeForm' import OptionButton from 'ui/OptionButton' interface PlanDetailsControlsProps { - setSelectedPlan: (x: IndividualPlan) => void - setValue: (x: string, y: string) => void + setSelectedPlan: (x?: Plan) => void + setValue: (x: string, y?: string) => void isSentryUpgrade: boolean } diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/ProPlanDetails/ProPlanDetails.test.jsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/ProPlanDetails/ProPlanDetails.test.jsx index 37c4fd575f..b693de02c3 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/ProPlanDetails/ProPlanDetails.test.jsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/ProPlanDetails/ProPlanDetails.test.jsx @@ -17,7 +17,7 @@ vi.mock('shared/plan/ScheduledPlanDetails', () => ({ const proPlanYear = { marketingName: 'Pro', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -32,7 +32,7 @@ const proPlanYear = { const sentryPlanMonth = { marketingName: 'Sentry Pro', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -47,7 +47,7 @@ const sentryPlanMonth = { const sentryPlanYear = { marketingName: 'Sentry Pro', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -63,7 +63,7 @@ const sentryPlanYear = { const allPlansWithoutSentry = [ { marketingName: 'Basic', - value: 'users-free', + value: Plans.USERS_FREE, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -75,7 +75,7 @@ const allPlansWithoutSentry = [ }, { marketingName: 'Pro', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -89,7 +89,7 @@ const allPlansWithoutSentry = [ proPlanYear, { marketingName: 'Pro', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -102,7 +102,7 @@ const allPlansWithoutSentry = [ }, { marketingName: 'Pro', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -121,7 +121,7 @@ const mockPlanData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/SentryPlanDetails/SentryPlanDetails.test.jsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/SentryPlanDetails/SentryPlanDetails.test.jsx index e2b3a06da2..ac58c76b43 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/SentryPlanDetails/SentryPlanDetails.test.jsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/SentryPlanDetails/SentryPlanDetails.test.jsx @@ -14,7 +14,7 @@ vi.mock('shared/plan/BenefitList', () => ({ default: () => 'Benefits List' })) const sentryPlanMonth = { marketingName: 'Sentry Pro', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -29,7 +29,7 @@ const sentryPlanMonth = { const sentryPlanYear = { marketingName: 'Sentry Pro', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -45,7 +45,7 @@ const sentryPlanYear = { const allPlans = [ { marketingName: 'Basic', - value: 'users-free', + value: Plans.USERS_FREE, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -57,7 +57,7 @@ const allPlans = [ }, { marketingName: 'Pro', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -70,7 +70,7 @@ const allPlans = [ }, { marketingName: 'Pro', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -84,7 +84,7 @@ const allPlans = [ }, { marketingName: 'Pro', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -97,7 +97,7 @@ const allPlans = [ }, { marketingName: 'Pro', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -118,7 +118,7 @@ const mockPlanData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/TeamPlanDetails/TeamPlanDetails.test.jsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/TeamPlanDetails/TeamPlanDetails.test.jsx index c10b9f53bf..70550640d5 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/TeamPlanDetails/TeamPlanDetails.test.jsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/TeamPlanDetails/TeamPlanDetails.test.jsx @@ -21,7 +21,7 @@ const teamPlanMonth = { billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, } const teamPlanYear = { @@ -30,13 +30,13 @@ const teamPlanYear = { billingRate: 'annually', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, } const allPlans = [ { marketingName: 'Basic', - value: 'users-free', + value: Plans.USERS_FREE, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -48,7 +48,7 @@ const allPlans = [ }, { marketingName: 'Pro', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -61,7 +61,7 @@ const allPlans = [ }, { marketingName: 'Pro', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/UpgradeDetails.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/UpgradeDetails.test.tsx index 1eac7a8672..420d280bc5 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/UpgradeDetails.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/UpgradeDetails.test.tsx @@ -2,6 +2,8 @@ import { render, screen } from '@testing-library/react' import { Suspense } from 'react' import { MemoryRouter, Route } from 'react-router-dom' +import { Plans } from 'shared/utils/billing' + import UpgradeDetails from './UpgradeDetails' vi.mock('./SentryPlanDetails', () => ({ @@ -16,7 +18,7 @@ vi.mock('./TeamPlanDetails', () => ({ const proPlanYear = { marketingName: 'Pro', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -30,7 +32,7 @@ const proPlanYear = { const proPlanMonth = { marketingName: 'Pro', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 10, benefits: [ @@ -45,7 +47,7 @@ const proPlanMonth = { const sentryPlanYear = { marketingName: 'Sentry Pro', baseUnitPrice: 10, - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', benefits: [ 'Includes 5 seats', @@ -59,7 +61,7 @@ const sentryPlanYear = { const sentryPlanMonth = { marketingName: 'Sentry Pro', baseUnitPrice: 10, - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', benefits: [ 'Includes 5 seats', @@ -76,7 +78,7 @@ const teamPlanYear = { billingRate: 'annually', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, } const teamPlanMonth = { @@ -85,7 +87,7 @@ const teamPlanMonth = { billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, } type WrapperClosure = ( diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/UpgradeDetails.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/UpgradeDetails.tsx index e4310c9077..22c452a6a4 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/UpgradeDetails.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeDetails/UpgradeDetails.tsx @@ -1,11 +1,10 @@ -import { IndividualPlan } from 'services/account' -import { isSentryPlan, isTeamPlan } from 'shared/utils/billing' +import { isSentryPlan, isTeamPlan, Plan } from 'shared/utils/billing' import ProPlanDetails from './ProPlanDetails' import SentryPlanDetails from './SentryPlanDetails' import TeamPlanDetails from './TeamPlanDetails' -function UpgradeDetails({ selectedPlan }: { selectedPlan: IndividualPlan }) { +function UpgradeDetails({ selectedPlan }: { selectedPlan: Plan }) { if (isSentryPlan(selectedPlan?.value)) { return } else if (isTeamPlan(selectedPlan?.value)) { diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/Controller.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/Controller.tsx index f0a9c4528a..e6461d1715 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/Controller.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/Controller.tsx @@ -1,22 +1,20 @@ import { UseFormRegister, UseFormSetValue } from 'react-hook-form' -import { IndividualPlan } from 'services/account' -import { isSentryPlan, isTeamPlan } from 'shared/utils/billing' +import { isSentryPlan, isTeamPlan, Plan, PlanName } from 'shared/utils/billing' import ProPlanController from './ProPlanController' import SentryPlanController from './SentryPlanController' import TeamPlanController from './TeamPlanController' -import { NewPlanType } from '../constants' import { UpgradeFormFields } from '../UpgradeForm' interface BillingControlsProps { seats: number - newPlan: NewPlanType - selectedPlan: NewPlanType + newPlan?: PlanName + selectedPlan: PlanName register: UseFormRegister setFormValue: UseFormSetValue - setSelectedPlan: (plan: IndividualPlan) => void + setSelectedPlan: (plan?: Plan) => void errors?: { seats?: { message?: string diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/BillingOptions/BillingOptions.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/BillingOptions/BillingOptions.test.tsx index e414846299..504290df7d 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/BillingOptions/BillingOptions.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/BillingOptions/BillingOptions.test.tsx @@ -14,7 +14,7 @@ import BillingOptions from './BillingOptions' const allPlans = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -26,7 +26,7 @@ const allPlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -39,7 +39,7 @@ const allPlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -58,7 +58,7 @@ const mockPlanDataResponse = { billingRate: 'monthly', marketingName: 'Pro Team', monthlyUploadLimit: 250, - value: 'test-plan', + value: Plans.USERS_PR_INAPPM, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', @@ -195,7 +195,7 @@ describe('BillingOptions', () => { await waitFor(() => expect(mockSetFormValue).toHaveBeenCalledWith( 'newPlan', - 'users-pr-inappm' + Plans.USERS_PR_INAPPM ) ) }) @@ -272,7 +272,7 @@ describe('BillingOptions', () => { await waitFor(() => expect(mockSetFormValue).toHaveBeenCalledWith( 'newPlan', - 'users-pr-inappy' + Plans.USERS_PR_INAPPY ) ) }) diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/BillingOptions/BillingOptions.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/BillingOptions/BillingOptions.tsx index b1258bde31..5d035ca321 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/BillingOptions/BillingOptions.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/BillingOptions/BillingOptions.tsx @@ -7,15 +7,16 @@ import { findProPlans, isAnnualPlan, isMonthlyPlan, + PlanName, Plans, } from 'shared/utils/billing' import OptionButton from 'ui/OptionButton' -import { NewPlanType, OptionPeriod, TimePeriods } from '../../../constants' +import { OptionPeriod, TimePeriods } from '../../../constants' import { UpgradeFormFields } from '../../../UpgradeForm' interface BillingControlsProps { - newPlan: NewPlanType + newPlan?: PlanName setFormValue: UseFormSetValue } diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/PriceCallout/PriceCallout.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/PriceCallout/PriceCallout.test.tsx index a2095fd26b..9a562ce5fe 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/PriceCallout/PriceCallout.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/PriceCallout/PriceCallout.test.tsx @@ -13,7 +13,7 @@ import PriceCallout from './PriceCallout' const availablePlans = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -25,7 +25,7 @@ const availablePlans = [ }, { marketingName: 'Pro', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -38,7 +38,7 @@ const availablePlans = [ }, { marketingName: 'Pro', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -51,7 +51,7 @@ const availablePlans = [ }, { marketingName: 'Team', - value: 'users-teamm', + value: Plans.USERS_TEAMM, billingRate: 'monthly', baseUnitPrice: 5, benefits: ['Patch coverage analysis'], @@ -59,7 +59,7 @@ const availablePlans = [ }, { marketingName: 'Team', - value: 'users-teamy', + value: Plans.USERS_TEAMY, billingRate: 'yearly', baseUnitPrice: 4, benefits: ['Patch coverage analysis'], diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/PriceCallout/PriceCallout.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/PriceCallout/PriceCallout.tsx index 077468a031..2a37250728 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/PriceCallout/PriceCallout.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/PriceCallout/PriceCallout.tsx @@ -8,6 +8,7 @@ import { formatNumberToUSD, getNextBillingDate, isAnnualPlan, + PlanName, Plans, } from 'shared/utils/billing' import { @@ -16,11 +17,10 @@ import { } from 'shared/utils/upgradeForm' import Icon from 'ui/Icon' -import { NewPlanType } from '../../../constants' import { UpgradeFormFields } from '../../../UpgradeForm' interface PriceCalloutProps { - newPlan: NewPlanType + newPlan?: PlanName seats: number setFormValue: UseFormSetValue } diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/ProPlanController.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/ProPlanController.test.tsx index a22ca88f1e..42e9536e65 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/ProPlanController.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/ProPlanController.test.tsx @@ -26,7 +26,7 @@ vi.mock('services/toastNotification', async () => { const basicPlan = { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -69,7 +69,7 @@ const proPlanYear = { const trialPlan = { marketingName: 'Pro Trial Team', - value: 'users-trial', + value: Plans.USERS_TRIAL, billingRate: null, baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], @@ -120,7 +120,7 @@ const mockPlanDataResponseMonthly = { billingRate: 'monthly', marketingName: 'Pro Team', monthlyUploadLimit: 250, - value: 'test-plan', + value: Plans.USERS_PR_INAPPM, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', @@ -136,7 +136,7 @@ const mockPlanDataResponseYearly = { billingRate: 'yearly', marketingName: 'Pro Team', monthlyUploadLimit: 250, - value: 'test-plan', + value: Plans.USERS_PR_INAPPY, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/ProPlanController.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/ProPlanController.tsx index 5046e480b2..3f4db3c556 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/ProPlanController.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/ProPlanController.tsx @@ -1,5 +1,6 @@ import { UseFormRegister, UseFormSetValue } from 'react-hook-form' +import { PlanName } from 'shared/utils/billing' import { MIN_NB_SEATS_PRO } from 'shared/utils/upgradeForm' import TextInput from 'ui/TextInput' @@ -7,12 +8,11 @@ import BillingOptions from './BillingOptions' import PriceCallout from './PriceCallout' import UserCount from './UserCount' -import { NewPlanType } from '../../constants' import { UpgradeFormFields } from '../../UpgradeForm' interface ProPlanControllerProps { seats: number - newPlan: NewPlanType + newPlan?: PlanName register: UseFormRegister setFormValue: UseFormSetValue diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/BillingOptions/BillingOptions.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/BillingOptions/BillingOptions.test.tsx index 8f5500bfae..8589de44b9 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/BillingOptions/BillingOptions.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/BillingOptions/BillingOptions.test.tsx @@ -14,7 +14,7 @@ import BillingOptions from './BillingOptions' const availablePlans = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -28,7 +28,7 @@ const availablePlans = [ }, { marketingName: 'Sentry Pro Team', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -43,7 +43,7 @@ const availablePlans = [ }, { marketingName: 'Sentry Pro Team', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -64,7 +64,7 @@ const mockPlanDataResponse = { billingRate: 'annual', marketingName: 'Sentry', monthlyUploadLimit: 250, - value: 'test-plan', + value: Plans.USERS_SENTRYY, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/BillingOptions/BillingOptions.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/BillingOptions/BillingOptions.tsx index f37285d328..8874b46db2 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/BillingOptions/BillingOptions.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/BillingOptions/BillingOptions.tsx @@ -7,15 +7,16 @@ import { findSentryPlans, isAnnualPlan, isMonthlyPlan, + PlanName, Plans, } from 'shared/utils/billing' import OptionButton from 'ui/OptionButton' -import { NewPlanType, OptionPeriod, TimePeriods } from '../../../constants' +import { OptionPeriod, TimePeriods } from '../../../constants' import { UpgradeFormFields } from '../../../UpgradeForm' interface BillingControlsProps { - newPlan: NewPlanType + newPlan?: PlanName setFormValue: UseFormSetValue } diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/PriceCallout/PriceCallout.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/PriceCallout/PriceCallout.test.tsx index 70e713f5e4..99733f76a3 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/PriceCallout/PriceCallout.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/PriceCallout/PriceCallout.test.tsx @@ -13,7 +13,7 @@ import PriceCallout from './PriceCallout' const availablePlans = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -25,7 +25,7 @@ const availablePlans = [ }, { marketingName: 'Sentry Pro Team', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -40,7 +40,7 @@ const availablePlans = [ }, { marketingName: 'Sentry Pro Team', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/PriceCallout/PriceCallout.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/PriceCallout/PriceCallout.tsx index de3b62c6d5..b0c2407cd5 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/PriceCallout/PriceCallout.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/PriceCallout/PriceCallout.tsx @@ -8,6 +8,7 @@ import { formatNumberToUSD, getNextBillingDate, isAnnualPlan, + PlanName, Plans, } from 'shared/utils/billing' import { @@ -17,11 +18,10 @@ import { } from 'shared/utils/upgradeForm' import Icon from 'ui/Icon' -import { NewPlanType } from '../../../constants' import { UpgradeFormFields } from '../../../UpgradeForm' interface PriceCalloutProps { - newPlan: NewPlanType + newPlan?: PlanName seats: number setFormValue: UseFormSetValue } @@ -52,7 +52,7 @@ const PriceCallout: React.FC = ({ if (isPerYear) { const nonBundledCost = calculateSentryNonBundledCost({ - baseUnitPrice: sentryPlanYear.baseUnitPrice, + baseUnitPrice: sentryPlanYear?.baseUnitPrice, }) return ( @@ -84,7 +84,7 @@ const PriceCallout: React.FC = ({ } const nonBundledCost = calculateSentryNonBundledCost({ - baseUnitPrice: sentryPlanMonth.baseUnitPrice, + baseUnitPrice: sentryPlanMonth?.baseUnitPrice, }) return (
diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/SentryPlanController.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/SentryPlanController.test.tsx index 72ccfd7bb0..2d48891335 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/SentryPlanController.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/SentryPlanController.test.tsx @@ -26,7 +26,7 @@ vi.mock('@stripe/react-stripe-js') const basicPlan = { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -39,7 +39,7 @@ const basicPlan = { const sentryPlanMonth = { marketingName: 'Sentry Pro', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -55,7 +55,7 @@ const sentryPlanMonth = { const sentryPlanYear = { marketingName: 'Sentry Pro', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -106,7 +106,7 @@ const mockPlanDataResponseMonthly = { billingRate: 'monthly', marketingName: 'Pro', monthlyUploadLimit: 2500, - value: 'test-plan', + value: Plans.USERS_SENTRYM, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', @@ -122,7 +122,7 @@ const mockPlanDataResponseYearly = { billingRate: 'yearly', marketingName: 'Pro', monthlyUploadLimit: 2500, - value: 'test-plan', + value: Plans.USERS_SENTRYY, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/SentryPlanController.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/SentryPlanController.tsx index beced2ec1f..91a7a1be81 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/SentryPlanController.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/SentryPlanController.tsx @@ -1,5 +1,6 @@ import { UseFormRegister, UseFormSetValue } from 'react-hook-form' +import { PlanName } from 'shared/utils/billing' import { MIN_SENTRY_SEATS } from 'shared/utils/upgradeForm' import TextInput from 'ui/TextInput' @@ -7,12 +8,11 @@ import BillingOptions from './BillingOptions' import PriceCallout from './PriceCallout' import UserCount from './UserCount' -import { NewPlanType } from '../../constants' import { UpgradeFormFields } from '../../UpgradeForm' interface SentryPlanControllerProps { seats: number - newPlan: NewPlanType + newPlan?: PlanName register: UseFormRegister setFormValue: UseFormSetValue errors?: { diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/BillingOptions/BillingOptions.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/BillingOptions/BillingOptions.test.tsx index 0dd2fec4e2..0de7ffb3e7 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/BillingOptions/BillingOptions.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/BillingOptions/BillingOptions.test.tsx @@ -14,7 +14,7 @@ import BillingOptions from './BillingOptions' const availablePlans = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -30,7 +30,7 @@ const availablePlans = [ billingRate: 'monthly', marketingName: 'Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, }, { baseUnitPrice: 4, @@ -38,7 +38,7 @@ const availablePlans = [ billingRate: 'annually', marketingName: 'Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, }, ] @@ -48,7 +48,7 @@ const mockPlanDataResponse = { billingRate: 'monthly', marketingName: 'Team', monthlyUploadLimit: 250, - value: 'test-plan', + value: Plans.USERS_TEAMM, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/BillingOptions/BillingOptions.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/BillingOptions/BillingOptions.tsx index 26a959e872..37650ff613 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/BillingOptions/BillingOptions.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/BillingOptions/BillingOptions.tsx @@ -7,15 +7,16 @@ import { findTeamPlans, isAnnualPlan, isMonthlyPlan, + PlanName, Plans, } from 'shared/utils/billing' import OptionButton from 'ui/OptionButton' -import { NewPlanType, OptionPeriod, TimePeriods } from '../../../constants' +import { OptionPeriod, TimePeriods } from '../../../constants' import { UpgradeFormFields } from '../../../UpgradeForm' interface BillingControlsProps { - newPlan: NewPlanType + newPlan?: PlanName setFormValue: UseFormSetValue } diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/ErrorBanner/ErrorBanner.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/ErrorBanner/ErrorBanner.test.tsx index 4d491832e5..1e9e6de888 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/ErrorBanner/ErrorBanner.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/ErrorBanner/ErrorBanner.test.tsx @@ -14,7 +14,7 @@ import ErrorBanner from './ErrorBanner' const basicPlan = { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -31,7 +31,7 @@ const teamPlanMonth = { billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, quantity: 10, } @@ -41,7 +41,7 @@ const teamPlanYear = { billingRate: 'annually', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, quantity: 5, } @@ -93,7 +93,7 @@ const mockPlanDataResponseMonthly = { billingRate: 'monthly', marketingName: 'Pro Team', monthlyUploadLimit: 2500, - value: 'test-plan', + value: Plans.USERS_TEAMM, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', @@ -108,7 +108,7 @@ const mockPlanDataResponseYearly = { billingRate: 'yearly', marketingName: 'Pro Team', monthlyUploadLimit: 2500, - value: 'test-plan', + value: Plans.USERS_TEAMM, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/ErrorBanner/ErrorBanner.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/ErrorBanner/ErrorBanner.tsx index 7cfc8a6a2f..473250cda3 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/ErrorBanner/ErrorBanner.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/ErrorBanner/ErrorBanner.tsx @@ -1,15 +1,12 @@ import { UseFormSetValue } from 'react-hook-form' import { useParams } from 'react-router-dom' -import { - IndividualPlan, - useAccountDetails, - useAvailablePlans, -} from 'services/account' +import { useAccountDetails, useAvailablePlans } from 'services/account' import { canApplySentryUpgrade, findProPlans, findSentryPlans, + Plan, } from 'shared/utils/billing' import { UPGRADE_FORM_TOO_MANY_SEATS_MESSAGE } from 'shared/utils/upgradeForm' @@ -24,7 +21,7 @@ interface Errors { interface ErrorBannerProps { errors: Errors setFormValue: UseFormSetValue - setSelectedPlan: (plan: IndividualPlan) => void + setSelectedPlan: (plan?: Plan) => void } export default function ErrorBanner({ @@ -37,7 +34,8 @@ export default function ErrorBanner({ const { data: accountDetails } = useAccountDetails({ provider, owner }) const { proPlanYear } = findProPlans({ plans }) const { sentryPlanYear } = findSentryPlans({ plans }) - const plan = accountDetails?.rootOrganization?.plan ?? accountDetails?.plan + const plan = + accountDetails?.rootOrganization?.plan?.value ?? accountDetails?.plan?.value const isSentryUpgrade = canApplySentryUpgrade({ plan, plans }) const yearlyProPlan = isSentryUpgrade ? sentryPlanYear : proPlanYear @@ -52,7 +50,7 @@ export default function ErrorBanner({ className="cursor-pointer font-semibold text-ds-blue-darker hover:underline" onClick={() => { setSelectedPlan(yearlyProPlan) - setFormValue('newPlan', yearlyProPlan.value, { + setFormValue('newPlan', yearlyProPlan?.value, { shouldValidate: true, }) }} diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/PriceCallout/PriceCallout.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/PriceCallout/PriceCallout.test.tsx index c3936d9cba..3d4de3e232 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/PriceCallout/PriceCallout.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/PriceCallout/PriceCallout.test.tsx @@ -13,7 +13,7 @@ import PriceCallout from './PriceCallout' const availablePlans = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -25,7 +25,7 @@ const availablePlans = [ }, { marketingName: 'Pro', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -38,7 +38,7 @@ const availablePlans = [ }, { marketingName: 'Team', - value: 'users-teamm', + value: Plans.USERS_TEAMM, billingRate: 'monthly', baseUnitPrice: 5, benefits: ['Patch coverage analysis'], @@ -46,7 +46,7 @@ const availablePlans = [ }, { marketingName: 'Team', - value: 'users-teamy', + value: Plans.USERS_TEAMY, billingRate: 'yearly', baseUnitPrice: 4, benefits: ['Patch coverage analysis'], diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/PriceCallout/PriceCallout.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/PriceCallout/PriceCallout.tsx index 943cf0d074..7967343499 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/PriceCallout/PriceCallout.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/PriceCallout/PriceCallout.tsx @@ -9,6 +9,7 @@ import { formatNumberToUSD, getNextBillingDate, isAnnualPlan, + PlanName, Plans, } from 'shared/utils/billing' import { @@ -18,11 +19,10 @@ import { } from 'shared/utils/upgradeForm' import Icon from 'ui/Icon' -import { NewPlanType } from '../../../constants' import { UpgradeFormFields } from '../../../UpgradeForm' interface PriceCalloutProps { - newPlan: NewPlanType + newPlan?: PlanName seats: number setFormValue: UseFormSetValue } diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/TeamPlanController.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/TeamPlanController.test.tsx index cf8cb10b71..baaeb7ef6a 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/TeamPlanController.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/TeamPlanController.test.tsx @@ -28,7 +28,7 @@ vi.mock('@stripe/react-stripe-js') const basicPlan = { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -45,7 +45,7 @@ const teamPlanMonth = { billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, quantity: 10, } @@ -55,7 +55,7 @@ const teamPlanYear = { billingRate: 'annually', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, quantity: 5, } @@ -107,7 +107,7 @@ const mockPlanDataResponseMonthly = { billingRate: 'monthly', marketingName: 'Pro Team', monthlyUploadLimit: 2500, - value: 'test-plan', + value: Plans.USERS_PR_INAPPM, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', @@ -123,7 +123,7 @@ const mockPlanDataResponseYearly = { billingRate: 'yearly', marketingName: 'Pro Team', monthlyUploadLimit: 2500, - value: 'test-plan', + value: Plans.USERS_PR_INAPPY, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/TeamPlanController.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/TeamPlanController.tsx index 972d55e779..c7d3b97948 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/TeamPlanController.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/TeamPlanController.tsx @@ -1,6 +1,6 @@ import { UseFormRegister, UseFormSetValue } from 'react-hook-form' -import { IndividualPlan } from 'services/account' +import { Plan, PlanName } from 'shared/utils/billing' import { MIN_NB_SEATS_PRO, TEAM_PLAN_MAX_ACTIVE_USERS, @@ -12,7 +12,6 @@ import ErrorBanner from './ErrorBanner' import PriceCallout from './PriceCallout' import UserCount from './UserCount' -import { NewPlanType } from '../../constants' import { UpgradeFormFields } from '../../UpgradeForm' interface Errors { @@ -23,10 +22,10 @@ interface Errors { interface PlanControllerProps { seats: number - newPlan: NewPlanType + newPlan?: PlanName register: UseFormRegister setFormValue: UseFormSetValue - setSelectedPlan: (plan: IndividualPlan) => void + setSelectedPlan: (plan?: Plan) => void errors?: Errors } diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/PlanTypeOptions/PlanTypeOptions.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/PlanTypeOptions/PlanTypeOptions.test.tsx index fc476c765d..0e02d3a6be 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/PlanTypeOptions/PlanTypeOptions.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/PlanTypeOptions/PlanTypeOptions.test.tsx @@ -7,13 +7,13 @@ import qs from 'qs' import { Suspense } from 'react' import { MemoryRouter, Route, useLocation } from 'react-router-dom' -import { Plans } from 'shared/utils/billing' +import { PlanName, Plans } from 'shared/utils/billing' import PlanTypeOptions from './PlanTypeOptions' const basicPlan = { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -26,7 +26,7 @@ const basicPlan = { const proPlanMonth = { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -40,7 +40,7 @@ const proPlanMonth = { const proPlanYear = { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -54,7 +54,7 @@ const proPlanYear = { const sentryPlanMonth = { marketingName: 'Sentry Pro Team', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -68,7 +68,7 @@ const sentryPlanMonth = { const sentryPlanYear = { marketingName: 'Sentry Pro Team', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -86,7 +86,7 @@ const teamPlanMonth = { billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, } const teamPlanYear = { @@ -95,12 +95,12 @@ const teamPlanYear = { billingRate: 'annually', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, } const trialPlan = { marketingName: 'Pro Trial Team', - value: 'users-trial', + value: Plans.USERS_TRIAL, billingRate: null, baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], @@ -182,7 +182,7 @@ const mockAccountDetailsTrial = { } type SetupArgs = { - planValue: string + planValue: PlanName hasSentryPlans: boolean hasTeamPlans: boolean } diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/PlanTypeOptions/PlanTypeOptions.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/PlanTypeOptions/PlanTypeOptions.tsx index 51bd452650..bd404e0488 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/PlanTypeOptions/PlanTypeOptions.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/PlanTypeOptions/PlanTypeOptions.tsx @@ -1,11 +1,7 @@ import { UseFormSetValue } from 'react-hook-form' import { useParams } from 'react-router-dom' -import { - IndividualPlan, - useAccountDetails, - useAvailablePlans, -} from 'services/account' +import { useAccountDetails, useAvailablePlans } from 'services/account' import { useLocationParams } from 'services/navigation' import { TierNames } from 'services/tier' import { @@ -15,6 +11,8 @@ import { findTeamPlans, isMonthlyPlan, isTeamPlan, + Plan, + PlanName, shouldDisplayTeamCard, } from 'shared/utils/billing' import { TEAM_PLAN_MAX_ACTIVE_USERS } from 'shared/utils/upgradeForm' @@ -26,8 +24,8 @@ import { UpgradeFormFields } from '../UpgradeForm' interface PlanTypeOptionsProps { setFormValue: UseFormSetValue - setSelectedPlan: (x: IndividualPlan) => void - newPlan: string + setSelectedPlan: (x?: Plan) => void + newPlan?: PlanName } const PlanTypeOptions: React.FC = ({ @@ -47,7 +45,8 @@ const PlanTypeOptions: React.FC = ({ }) const hasTeamPlans = shouldDisplayTeamCard({ plans }) - const plan = accountDetails?.rootOrganization?.plan ?? accountDetails?.plan + const plan = + accountDetails?.rootOrganization?.plan?.value ?? accountDetails?.plan?.value const isSentryUpgrade = canApplySentryUpgrade({ plan, plans }) const yearlyProPlan = isSentryUpgrade ? sentryPlanYear : proPlanYear diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpdateBlurb/UpdateBlurb.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpdateBlurb/UpdateBlurb.tsx index 99cdfcbc6e..df0e440cdd 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpdateBlurb/UpdateBlurb.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpdateBlurb/UpdateBlurb.tsx @@ -1,9 +1,12 @@ import { z } from 'zod' import { PlanSchema } from 'services/account' -import { isAnnualPlan, isFreePlan, isTeamPlan } from 'shared/utils/billing' - -import { NewPlanType } from '../constants' +import { + isAnnualPlan, + isFreePlan, + isTeamPlan, + PlanName, +} from 'shared/utils/billing' const UpdateBlurb = ({ currentPlan, @@ -14,7 +17,7 @@ const UpdateBlurb = ({ }: { currentPlan?: z.infer selectedPlan?: z.infer - newPlanName: NewPlanType + newPlanName?: PlanName seats: number nextBillingDate: string }) => { diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpdateButton/UpdateButton.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpdateButton/UpdateButton.tsx index 8795c664b4..c3dd67e899 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpdateButton/UpdateButton.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpdateButton/UpdateButton.tsx @@ -2,15 +2,13 @@ import React from 'react' import { useParams } from 'react-router-dom' import { useAccountDetails } from 'services/account' -import { isFreePlan } from 'shared/utils/billing' +import { isFreePlan, PlanName } from 'shared/utils/billing' import Button from 'ui/Button' -import { NewPlanType } from '../constants' - interface BillingControlsProps { seats: number isValid: boolean - newPlan: NewPlanType + newPlan?: PlanName } const UpdateButton: React.FC = ({ @@ -21,7 +19,7 @@ const UpdateButton: React.FC = ({ const { provider, owner } = useParams<{ provider: string; owner: string }>() const { data: accountDetails } = useAccountDetails({ provider, owner }) - const currentPlanValue = accountDetails?.plan?.value || '0' + const currentPlanValue = accountDetails?.plan?.value const currentPlanQuantity = accountDetails?.plan?.quantity || 0 const isSamePlan = newPlan === currentPlanValue diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpgradeForm.test.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpgradeForm.test.tsx index 1efdd06797..45d2e808d4 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpgradeForm.test.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpgradeForm.test.tsx @@ -6,9 +6,9 @@ import { setupServer } from 'msw/node' import { Suspense } from 'react' import { MemoryRouter, Route, useLocation } from 'react-router-dom' -import { IndividualPlan, TrialStatuses } from 'services/account' +import { TrialStatuses } from 'services/account' import { accountDetailsParsedObj } from 'services/account/mocks' -import { Plans } from 'shared/utils/billing' +import { Plan, Plans } from 'shared/utils/billing' import UpgradeForm from './UpgradeForm' @@ -29,7 +29,7 @@ vi.mock('@sentry/react') const basicPlan = { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -72,7 +72,7 @@ const proPlanYear = { const sentryPlanMonth = { marketingName: 'Sentry Pro Team', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -88,7 +88,7 @@ const sentryPlanMonth = { const sentryPlanYear = { marketingName: 'Sentry Pro Team', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -108,7 +108,7 @@ const teamPlanMonth = { billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, } const teamPlanYear = { @@ -117,12 +117,12 @@ const teamPlanYear = { billingRate: 'annually', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, } const trialPlan = { marketingName: 'Pro Trial Team', - value: 'users-trial', + value: Plans.USERS_TRIAL, billingRate: null, baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], @@ -198,7 +198,7 @@ const mockPlanDataResponseMonthly = { billingRate: 'monthly', marketingName: 'Pro Team', monthlyUploadLimit: 250, - value: 'test-plan', + value: Plans.USERS_PR_INAPPM, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', @@ -214,7 +214,7 @@ const mockPlanDataResponseYearly = { billingRate: 'yearly', marketingName: 'Pro Team', monthlyUploadLimit: 250, - value: 'test-plan', + value: Plans.USERS_PR_INAPPY, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', @@ -231,11 +231,6 @@ const queryClient = new QueryClient({ retry: false, }, }, - logger: { - error: () => {}, - warn: () => {}, - log: () => {}, - }, }) const server = setupServer() @@ -320,7 +315,7 @@ describe('UpgradeForm', () => { } }), http.patch( - '/internal/:provider/:owner/account-details/', + `/internal/:provider/:owner/account-details/`, async (info) => { if (!successfulPatchRequest) { if (errorDetails) { @@ -379,7 +374,7 @@ describe('UpgradeForm', () => { setSelectedPlan: vi.fn(), selectedPlan: { value: Plans.USERS_PR_INAPPY, - } as NonNullable, + } as NonNullable, } it('renders the organization and owner titles', async () => { setup({ planValue: Plans.USERS_BASIC }) @@ -687,7 +682,7 @@ describe('UpgradeForm', () => { setSelectedPlan: vi.fn(), selectedPlan: { value: Plans.USERS_PR_INAPPY, - } as NonNullable, + } as NonNullable, } it('renders the organization and owner titles', async () => { setup({ planValue: Plans.USERS_PR_INAPPM }) @@ -990,7 +985,7 @@ describe('UpgradeForm', () => { setSelectedPlan: vi.fn(), selectedPlan: { value: Plans.USERS_PR_INAPPY, - } as NonNullable, + } as NonNullable, } it('renders the organization and owner titles', async () => { setup({ planValue: Plans.USERS_PR_INAPPY }) @@ -1317,7 +1312,7 @@ describe('UpgradeForm', () => { setSelectedPlan: vi.fn(), selectedPlan: { value: Plans.USERS_SENTRYY, - } as NonNullable, + } as NonNullable, } it('renders the organization and owner titles', async () => { setup({ @@ -1637,7 +1632,7 @@ describe('UpgradeForm', () => { setSelectedPlan: vi.fn(), selectedPlan: { value: Plans.USERS_TEAMY, - } as NonNullable, + } as NonNullable, } it('renders the organization and owner titles', async () => { setup({ @@ -1984,7 +1979,7 @@ describe('UpgradeForm', () => { setSelectedPlan: vi.fn(), selectedPlan: { value: Plans.USERS_PR_INAPPY, - } as NonNullable, + } as NonNullable, } describe('user chooses less than the number of active users', () => { it('does not display an error', async () => { diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpgradeForm.tsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpgradeForm.tsx index 349cabf212..85b1ed5384 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpgradeForm.tsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/UpgradeForm.tsx @@ -4,7 +4,6 @@ import { useForm } from 'react-hook-form' import { useParams } from 'react-router-dom' import { - IndividualPlan, useAccountDetails, useAvailablePlans, usePlanData, @@ -13,6 +12,8 @@ import { canApplySentryUpgrade, getNextBillingDate, isTeamPlan, + Plan, + PlanName, } from 'shared/utils/billing' import { getDefaultValuesUpgradeForm, @@ -21,7 +22,6 @@ import { MIN_SENTRY_SEATS, } from 'shared/utils/upgradeForm' -import { NewPlanType } from './constants' import Controller from './Controllers/Controller' import { useUpgradeControls } from './hooks' import PlanTypeOptions from './PlanTypeOptions' @@ -34,12 +34,12 @@ type URLParams = { } type UpgradeFormProps = { - selectedPlan: NonNullable - setSelectedPlan: (plan: IndividualPlan) => void + selectedPlan: NonNullable + setSelectedPlan: (plan?: Plan) => void } export type UpgradeFormFields = { - newPlan: NewPlanType + newPlan?: PlanName seats: number } @@ -67,7 +67,7 @@ function UpgradeForm({ selectedPlan, setSelectedPlan }: UpgradeFormProps) { formState: { isValid, errors }, setValue: setFormValue, trigger, - } = useForm({ + } = useForm({ defaultValues: getDefaultValuesUpgradeForm({ accountDetails, plans, @@ -108,7 +108,7 @@ function UpgradeForm({ selectedPlan, setSelectedPlan }: UpgradeFormProps) { newPlan={newPlan} /> { + const { provider, owner } = useParams() + const queryClient = useQueryClient() + const history = useHistory() + const addToast = useAddNotification() + const { mutate } = useUpgradePlan({ provider, owner }) + const setPlanUpdatedNotification = useSetPlanUpdatedNotification() + + function upgradePlan({ seats, newPlan }: UpgradeFormFields) { + return mutate( + { + seats, + newPlan: newPlan!, + }, + { + onSuccess: () => { + queryClient.invalidateQueries(['accountDetails']) + setPlanUpdatedNotification({ + alertOption: 'success', + }) + history.push(`/plan/${provider}/${owner}`) + }, + onError: (error: any) => { + addToast({ + type: 'error', + text: error?.data?.detail || 'Something went wrong', + }) + }, + } + ) + } + + return { + upgradePlan, + } +} diff --git a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradePlanPage.test.jsx b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradePlanPage.test.jsx index 74def6bd24..b6dcebf94d 100644 --- a/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradePlanPage.test.jsx +++ b/src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradePlanPage.test.jsx @@ -20,7 +20,7 @@ vi.mock('./UpgradeForm', () => ({ default: () => 'UpgradeForm' })) const plans = [ { marketingName: 'Basic', - value: 'users-free', + value: Plans.USERS_FREE, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -32,7 +32,7 @@ const plans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -45,7 +45,7 @@ const plans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -58,7 +58,7 @@ const plans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -71,7 +71,7 @@ const plans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -86,7 +86,7 @@ const plans = [ const sentryPlanMonth = { marketingName: 'Sentry Pro Team', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -101,7 +101,7 @@ const sentryPlanMonth = { const sentryPlanYear = { marketingName: 'Sentry Pro Team', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -120,7 +120,7 @@ const teamPlanMonth = { billingRate: 'monthly', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamm', + value: Plans.USERS_TEAMM, } const teamPlanYear = { @@ -129,7 +129,7 @@ const teamPlanYear = { billingRate: 'annually', marketingName: 'Users Team', monthlyUploadLimit: 2500, - value: 'users-teamy', + value: Plans.USERS_TEAMY, } const mockPlanData = { @@ -138,7 +138,7 @@ const mockPlanData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: TrialStatuses.NOT_STARTED, trialStartDate: '', trialEndDate: '', diff --git a/src/pages/PullRequestPage/Header/HeaderDefault/HeaderDefault.tsx b/src/pages/PullRequestPage/Header/HeaderDefault/HeaderDefault.tsx index eddb52502c..2c6096da60 100644 --- a/src/pages/PullRequestPage/Header/HeaderDefault/HeaderDefault.tsx +++ b/src/pages/PullRequestPage/Header/HeaderDefault/HeaderDefault.tsx @@ -2,6 +2,7 @@ import cs from 'classnames' import capitalize from 'lodash/capitalize' import { useParams } from 'react-router-dom' +import { Provider } from 'shared/api/helpers' import { formatTimeToNow } from 'shared/utils/dates' import { getProviderPullURL } from 'shared/utils/provider' import A from 'ui/A' @@ -13,7 +14,7 @@ import { usePullHeadData } from './hooks' import { pullStateToColor } from '../constants' interface URLParams { - provider: string + provider: Provider owner: string repo: string pullId: string diff --git a/src/pages/PullRequestPage/Header/HeaderTeam/HeaderTeam.tsx b/src/pages/PullRequestPage/Header/HeaderTeam/HeaderTeam.tsx index fc2b0e337f..2e32879725 100644 --- a/src/pages/PullRequestPage/Header/HeaderTeam/HeaderTeam.tsx +++ b/src/pages/PullRequestPage/Header/HeaderTeam/HeaderTeam.tsx @@ -2,6 +2,7 @@ import cs from 'classnames' import capitalize from 'lodash/capitalize' import { useParams } from 'react-router-dom' +import { Provider } from 'shared/api/helpers' import { formatTimeToNow } from 'shared/utils/dates' import { getProviderPullURL } from 'shared/utils/provider' import A from 'ui/A' @@ -14,7 +15,7 @@ import { usePullHeadDataTeam } from './hooks' import { pullStateToColor } from '../constants' interface URLParams { - provider: string + provider: Provider owner: string repo: string pullId: string diff --git a/src/pages/RepoPage/ActivationAlert/ActivationAlert.test.tsx b/src/pages/RepoPage/ActivationAlert/ActivationAlert.test.tsx index 66aa517888..1305713210 100644 --- a/src/pages/RepoPage/ActivationAlert/ActivationAlert.test.tsx +++ b/src/pages/RepoPage/ActivationAlert/ActivationAlert.test.tsx @@ -4,6 +4,8 @@ import { graphql, HttpResponse } from 'msw' import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' +import { PlanName, Plans } from 'shared/utils/billing' + import ActivationAlert from './ActivationAlert' vi.mock('./FreePlanSeatsTakenAlert', () => ({ @@ -48,7 +50,7 @@ const mockTrialData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: 'ONGOING', trialStartDate: '2023-01-01T08:55:25', trialEndDate: '2023-01-10T08:55:25', @@ -61,7 +63,7 @@ const mockTrialData = { describe('ActivationAlert', () => { function setup( privateRepos = true, - value = 'users-basic', + value: PlanName = Plans.USERS_BASIC, hasSeatsLeft = true ) { server.use( @@ -81,7 +83,7 @@ describe('ActivationAlert', () => { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, }, }, }, @@ -101,7 +103,7 @@ describe('ActivationAlert', () => { }) it('renders FreePlanSeatsTakenAlert when on free plan and no seats left', async () => { - setup(false, 'users-basic', false) + setup(false, Plans.USERS_BASIC, false) render(, { wrapper }) const freePlanSeatsTakenAlert = await screen.findByText( @@ -111,7 +113,7 @@ describe('ActivationAlert', () => { }) it('renders PaidPlanSeatsTakenAlert when on paid plan and no seats left', async () => { - setup(false, 'users-pro', false) + setup(false, Plans.USERS_PR_INAPPM, false) render(, { wrapper }) const paidPlanSeatsTakenAlert = await screen.findByText( @@ -121,7 +123,7 @@ describe('ActivationAlert', () => { }) it('renders ActivationRequiredAlert when on paid plan and some seats left', async () => { - setup(false, 'users-pro', true) + setup(false, Plans.USERS_PR_INAPPM, true) render(, { wrapper }) const activationRequiredAlert = await screen.findByText( diff --git a/src/pages/RepoPage/CoverageOnboarding/ActivationBanner/ActivationBanner.test.tsx b/src/pages/RepoPage/CoverageOnboarding/ActivationBanner/ActivationBanner.test.tsx index 604b89e28d..0fecd53bcf 100644 --- a/src/pages/RepoPage/CoverageOnboarding/ActivationBanner/ActivationBanner.test.tsx +++ b/src/pages/RepoPage/CoverageOnboarding/ActivationBanner/ActivationBanner.test.tsx @@ -4,6 +4,8 @@ import { graphql, HttpResponse } from 'msw' import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' +import { PlanName, Plans } from 'shared/utils/billing' + import ActivationBanner from './ActivationBanner' vi.mock('./TrialEligibleBanner', () => ({ @@ -48,7 +50,7 @@ const mockTrialData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: 'ONGOING', trialStartDate: '2023-01-01T08:55:25', trialEndDate: '2023-01-10T08:55:25', @@ -62,7 +64,7 @@ describe('ActivationBanner', () => { function setup( privateRepos = true, trialStatus = 'NOT_STARTED', - value = 'users-basic', + value: PlanName = Plans.USERS_BASIC, hasSeatsLeft = true ) { server.use( @@ -83,7 +85,7 @@ describe('ActivationBanner', () => { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, }, }, }, @@ -101,7 +103,7 @@ describe('ActivationBanner', () => { }) it('does not render trial eligible banner if user is not eligible to trial', async () => { - setup(false, 'ONGOING', 'users-basic', true) + setup(false, 'ONGOING', Plans.USERS_BASIC, true) const { container } = render(, { wrapper }) await waitFor(() => queryClient.isFetching) @@ -111,7 +113,7 @@ describe('ActivationBanner', () => { }) it('renders activation required banner if user is not on free plan and has seats left', async () => { - setup(true, 'ONGOING', 'users-pro', true) + setup(true, 'ONGOING', Plans.USERS_PR_INAPPM, true) render(, { wrapper }) const ActivationRequiredBanner = await screen.findByText( @@ -121,7 +123,7 @@ describe('ActivationBanner', () => { }) it('renders seats limit reached banner if user has no seats left and on free plan', async () => { - setup(true, 'ONGOING', 'users-basic', false) + setup(true, 'ONGOING', Plans.USERS_BASIC, false) render(, { wrapper }) const FreePlanSeatsLimitBanner = await screen.findByText( @@ -131,7 +133,7 @@ describe('ActivationBanner', () => { }) it('renders seats limit reached banner if user has no seats left and on paid plan', async () => { - setup(true, 'ONGOING', 'users-inappy', false) + setup(true, 'ONGOING', Plans.USERS_PR_INAPPY, false) render(, { wrapper }) const PaidPlanSeatsLimitBanner = await screen.findByText( diff --git a/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.tsx b/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.tsx index 6ee1cd2869..a957619aaf 100644 --- a/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.tsx +++ b/src/pages/RepoPage/CoverageOnboarding/CircleCI/CircleCI.tsx @@ -6,6 +6,7 @@ import { } from 'services/codecovEventMetrics' import { useOrgUploadToken } from 'services/orgUploadToken' import { useRepo } from 'services/repo' +import { Provider } from 'shared/api/helpers' import { useFlags } from 'shared/featureFlags' import { providerToInternalProvider } from 'shared/utils/provider' import A from 'ui/A' @@ -25,7 +26,7 @@ workflows: ` interface URLParams { - provider: string + provider: Provider owner: string repo: string } @@ -51,7 +52,7 @@ function CircleCI() { diff --git a/src/pages/RepoPage/CoverageOnboarding/NewRepoTab.tsx b/src/pages/RepoPage/CoverageOnboarding/NewRepoTab.tsx index 50bdd67712..5d20079772 100644 --- a/src/pages/RepoPage/CoverageOnboarding/NewRepoTab.tsx +++ b/src/pages/RepoPage/CoverageOnboarding/NewRepoTab.tsx @@ -10,6 +10,7 @@ import { } from 'services/codecovEventMetrics' import { useNavLinks } from 'services/navigation' import { useRepo } from 'services/repo' +import { Provider } from 'shared/api/helpers' import { useRedirect } from 'shared/useRedirect' import { providerToName } from 'shared/utils' import A from 'ui/A' @@ -37,7 +38,7 @@ const CI_PROVIDERS = { type CIProviderValue = (typeof CI_PROVIDERS)[keyof typeof CI_PROVIDERS] type CIUrls = Record -const getInitialProvider = (provider: string, path: string, urls: CIUrls) => { +const getInitialProvider = (provider: Provider, path: string, urls: CIUrls) => { const defaultProvider = providerToName(provider) !== 'Github' ? CI_PROVIDERS.OtherCI @@ -52,7 +53,7 @@ const getInitialProvider = (provider: string, path: string, urls: CIUrls) => { } interface CISelectorProps { - provider: string + provider: Provider owner: string repo: string } @@ -124,7 +125,7 @@ function Content() { } interface URLParams { - provider: string + provider: Provider owner: string repo: string } diff --git a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/FailedTestsTable/FailedTestsTable.test.tsx b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/FailedTestsTable/FailedTestsTable.test.tsx index 7941639294..18e431128c 100644 --- a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/FailedTestsTable/FailedTestsTable.test.tsx +++ b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/FailedTestsTable/FailedTestsTable.test.tsx @@ -11,6 +11,8 @@ import { setupServer } from 'msw/node' import { mockIsIntersecting } from 'react-intersection-observer/test-utils' import { MemoryRouter, Route } from 'react-router-dom' +import { Plans } from 'shared/utils/billing' + import FailedTestsTable from './FailedTestsTable' import { @@ -132,7 +134,7 @@ interface SetupArgs { describe('FailedTestsTable', () => { function setup({ noEntries = false, - planValue = 'users-enterprisem', + planValue = Plans.USERS_ENTERPRISEM, isPrivate = false, }: SetupArgs) { const queryClient = new QueryClient({ @@ -215,7 +217,7 @@ describe('FailedTestsTable', () => { describe('when plan is team plan', () => { it('does not render flake rate column', async () => { const { queryClient } = setup({ - planValue: 'users-teamm', + planValue: Plans.USERS_TEAMM, isPrivate: true, }) render(, { @@ -232,7 +234,7 @@ describe('FailedTestsTable', () => { describe('when plan is free', () => { it('does not render flake rate column', async () => { const { queryClient } = setup({ - planValue: 'users-free', + planValue: Plans.USERS_FREE, isPrivate: true, }) render(, { diff --git a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/MetricsSection/MetricsSection.test.tsx b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/MetricsSection/MetricsSection.test.tsx index 4b9cfbae7a..b67cd0b310 100644 --- a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/MetricsSection/MetricsSection.test.tsx +++ b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/MetricsSection/MetricsSection.test.tsx @@ -6,12 +6,14 @@ import { setupServer } from 'msw/node' import { PropsWithChildren, Suspense } from 'react' import { MemoryRouter, Route, useLocation } from 'react-router-dom' +import { PlanName, Plans } from 'shared/utils/billing' + import MetricsSection, { historicalTrendToCopy } from './MetricsSection' import { TestResultsFilterParameter } from '../hooks/useInfiniteTestResults/useInfiniteTestResults' const mockAggResponse = ( - planValue = 'users-enterprisem', + planValue: PlanName = Plans.USERS_ENTERPRISEM, isPrivate = false ) => ({ owner: { @@ -101,7 +103,10 @@ afterAll(() => { }) describe('MetricsSection', () => { - function setup(planValue = 'users-enterprisem', isPrivate = false) { + function setup( + planValue: PlanName = Plans.USERS_ENTERPRISEM, + isPrivate = false + ) { const user = userEvent.setup() server.use( @@ -419,7 +424,7 @@ describe('MetricsSection', () => { describe('when on team plan', () => { describe('when repo is private', () => { it('does not render total flaky tests card', async () => { - setup('users-teamm', true) + setup(Plans.USERS_TEAMM, true) render(, { wrapper: wrapper('/gh/owner/repo/tests/main'), }) @@ -431,7 +436,7 @@ describe('MetricsSection', () => { }) it('does not render avg flaky tests card', async () => { - setup('users-teamm', true) + setup(Plans.USERS_TEAMM, true) render(, { wrapper: wrapper('/gh/owner/repo/tests/main'), }) @@ -445,7 +450,7 @@ describe('MetricsSection', () => { describe('when repo is public', () => { it('renders total flaky tests card', async () => { - setup('users-teamm', false) + setup(Plans.USERS_TEAMM, false) render(, { wrapper: wrapper('/gh/owner/repo/tests/main'), }) @@ -457,7 +462,7 @@ describe('MetricsSection', () => { }) it('renders avg flaky tests card', async () => { - setup('users-teamm', false) + setup(Plans.USERS_TEAMM, false) render(, { wrapper: wrapper('/gh/owner/repo/tests/main'), }) @@ -473,7 +478,7 @@ describe('MetricsSection', () => { describe('when on free plan', () => { describe('when repo is private', () => { it('does not render total flaky tests card', async () => { - setup('users-basic', true) + setup(Plans.USERS_BASIC, true) render(, { wrapper: wrapper('/gh/owner/repo/tests/main'), }) @@ -485,7 +490,7 @@ describe('MetricsSection', () => { }) it('does not render avg flaky tests card', async () => { - setup('users-basic', true) + setup(Plans.USERS_BASIC, true) render(, { wrapper: wrapper('/gh/owner/repo/tests/main'), }) @@ -499,7 +504,7 @@ describe('MetricsSection', () => { describe('when repo is public', () => { it('renders total flaky tests card', async () => { - setup('users-basic', false) + setup(Plans.USERS_BASIC, false) render(, { wrapper: wrapper('/gh/owner/repo/tests/main'), }) @@ -511,7 +516,7 @@ describe('MetricsSection', () => { }) it('renders avg flaky tests card', async () => { - setup('users-basic', false) + setup(Plans.USERS_BASIC, false) render(, { wrapper: wrapper('/gh/owner/repo/tests/main'), }) diff --git a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useInfiniteTestResults/useInfiniteTestResults.test.tsx b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useInfiniteTestResults/useInfiniteTestResults.test.tsx index 6d8019c623..f8db7f50c1 100644 --- a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useInfiniteTestResults/useInfiniteTestResults.test.tsx +++ b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useInfiniteTestResults/useInfiniteTestResults.test.tsx @@ -3,12 +3,14 @@ import { renderHook, waitFor } from '@testing-library/react' import { graphql, HttpResponse } from 'msw' import { setupServer } from 'msw/node' +import { Plans } from 'shared/utils/billing' + import { useInfiniteTestResults } from './useInfiniteTestResults' const mockTestResults = { owner: { plan: { - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, }, repository: { __typename: 'Repository', @@ -78,7 +80,7 @@ const mockNotFoundError = { message: 'Repository not found', }, plan: { - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, }, }, } @@ -86,7 +88,7 @@ const mockNotFoundError = { const mockOwnerNotActivatedError = { owner: { plan: { - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, }, repository: { __typename: 'OwnerNotActivatedError', diff --git a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useInfiniteTestResults/useInfiniteTestResults.tsx b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useInfiniteTestResults/useInfiniteTestResults.tsx index 9cedc862bc..101ae8050b 100644 --- a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useInfiniteTestResults/useInfiniteTestResults.tsx +++ b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useInfiniteTestResults/useInfiniteTestResults.tsx @@ -12,6 +12,7 @@ import { } from 'services/repo' import Api from 'shared/api' import { type NetworkErrorObject, rejectNetworkError } from 'shared/api/helpers' +import { PlanName, Plans } from 'shared/utils/billing' import { mapEdges } from 'shared/utils/graphql' import A from 'ui/A' @@ -63,7 +64,7 @@ const GetTestResultsSchema = z.object({ .object({ plan: z .object({ - value: z.string(), + value: z.nativeEnum(Plans), }) .nullable(), repository: z.discriminatedUnion('__typename', [ @@ -178,7 +179,7 @@ interface UseTestResultsArgs { testResults: TestResult[] pageInfo: { endCursor: string | null; hasNextPage: boolean } private: boolean | null - plan: string | null + plan: PlanName | null defaultBranch: string | null totalCount: number | null }> diff --git a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useTestResultsAggregates/useTestResultsAggregates.tsx b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useTestResultsAggregates/useTestResultsAggregates.tsx index 4473187420..851fac6f14 100644 --- a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useTestResultsAggregates/useTestResultsAggregates.tsx +++ b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useTestResultsAggregates/useTestResultsAggregates.tsx @@ -6,13 +6,14 @@ import { MeasurementInterval } from 'pages/RepoPage/shared/constants' import { RepoNotFoundErrorSchema } from 'services/repo' import Api from 'shared/api' import { NetworkErrorObject, rejectNetworkError } from 'shared/api/helpers' +import { Plans } from 'shared/utils/billing' const TestResultsAggregatesSchema = z.object({ owner: z .object({ plan: z .object({ - value: z.string(), + value: z.nativeEnum(Plans), }) .nullable(), repository: z.discriminatedUnion('__typename', [ diff --git a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useTestResultsAggregates/useTestsResultsAggregates.test.tsx b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useTestResultsAggregates/useTestsResultsAggregates.test.tsx index 1505050332..94d8666917 100644 --- a/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useTestResultsAggregates/useTestsResultsAggregates.test.tsx +++ b/src/pages/RepoPage/FailedTestsTab/FailedTestsPage/hooks/useTestResultsAggregates/useTestsResultsAggregates.test.tsx @@ -5,6 +5,8 @@ import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' import { MockInstance } from 'vitest' +import { Plans } from 'shared/utils/billing' + import { useTestResultsAggregates } from './useTestResultsAggregates' const queryClient = new QueryClient({ @@ -41,7 +43,7 @@ const mockNotFoundError = { message: 'repo not found', }, plan: { - value: 'users-basic', + value: Plans.USERS_BASIC, }, }, } @@ -52,7 +54,7 @@ const mockIncorrectResponse = { invalid: 'invalid', }, plan: { - value: 'users-basic', + value: Plans.USERS_BASIC, }, }, } @@ -60,7 +62,7 @@ const mockIncorrectResponse = { const mockResponse = { owner: { plan: { - value: 'users-basic', + value: Plans.USERS_BASIC, }, repository: { __typename: 'Repository', diff --git a/src/pages/SyncProviderPage/SyncButton.tsx b/src/pages/SyncProviderPage/SyncButton.tsx index 4e81d28f01..5044a1a8e5 100644 --- a/src/pages/SyncProviderPage/SyncButton.tsx +++ b/src/pages/SyncProviderPage/SyncButton.tsx @@ -1,8 +1,10 @@ import { useNavLinks } from 'services/navigation' -import { providerImage, providerToName } from 'shared/utils/provider' +import { Provider } from 'shared/api/helpers' +import { loginProviderImage } from 'shared/utils/loginProviders' +import { providerToName } from 'shared/utils/provider' interface SyncButtonProps { - provider: 'gh' | 'gl' | 'bb' | 'ghe' | 'gle' | 'bbs' + provider: Provider } const SyncButton: React.FC = ({ provider }) => { @@ -19,7 +21,7 @@ const SyncButton: React.FC = ({ provider }) => { {`Logo Sync with {providerToName(provider)} diff --git a/src/services/account/mocks.ts b/src/services/account/mocks.ts index b35bdd60e4..dffcb14748 100644 --- a/src/services/account/mocks.ts +++ b/src/services/account/mocks.ts @@ -1,3 +1,5 @@ +import { Plans } from 'shared/utils/billing' + /* eslint-disable camelcase */ export const invoiceObject = { amountDue: 1407.0, @@ -39,7 +41,7 @@ export const accountDetailsObject = { plan_auto_activate: true, plan: { marketing_name: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billing_rate: 'monthly', base_unit_price: 12, benefits: [ @@ -78,7 +80,7 @@ export const accountDetailsObject = { end: 1636479475, start: 1634910008, }, - plan_name: 'users-pr-inappm', + plan_name: Plans.USERS_PR_INAPPM, quantity: 21, }, { @@ -90,7 +92,7 @@ export const accountDetailsObject = { end: 1636479475, start: 1634910008, }, - plan_name: 'users-pr-inappm', + plan_name: Plans.USERS_PR_INAPPM, quantity: 23, }, ], @@ -153,7 +155,7 @@ export const accountDetailsParsedObj = { planAutoActivate: true, plan: { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -192,7 +194,7 @@ export const accountDetailsParsedObj = { end: 1636479475, start: 1634910008, }, - planName: 'users-pr-inappm', + planName: Plans.USERS_PR_INAPPM, quantity: 21, }, { @@ -204,7 +206,7 @@ export const accountDetailsParsedObj = { end: 1636479475, start: 1634910008, }, - planName: 'users-pr-inappm', + planName: Plans.USERS_PR_INAPPM, quantity: 23, }, ], diff --git a/src/services/account/useAccountDetails.ts b/src/services/account/useAccountDetails.ts index 2df7f01843..3395d707e1 100644 --- a/src/services/account/useAccountDetails.ts +++ b/src/services/account/useAccountDetails.ts @@ -3,6 +3,7 @@ import { z } from 'zod' import Api from 'shared/api' import { NetworkErrorObject } from 'shared/api/helpers' +import { Plans } from 'shared/utils/billing' const InvoiceSchema = z .object({ @@ -120,7 +121,7 @@ export const PlanSchema = z marketingName: z.string(), monthlyUploadLimit: z.number().nullish(), quantity: z.number().nullish(), - value: z.string(), + value: z.nativeEnum(Plans), trialDays: z.number().nullish(), }) .nullable() diff --git a/src/services/account/useAvailablePlans.test.tsx b/src/services/account/useAvailablePlans.test.tsx index 427f86cee3..4924fa8653 100644 --- a/src/services/account/useAvailablePlans.test.tsx +++ b/src/services/account/useAvailablePlans.test.tsx @@ -3,12 +3,14 @@ import { renderHook, waitFor } from '@testing-library/react' import { graphql, HttpResponse } from 'msw' import { setupServer } from 'msw/node' +import { Plans } from 'shared/utils/billing' + import { useAvailablePlans } from './useAvailablePlans' const mockAvailablePlans = [ { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ @@ -20,7 +22,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -33,7 +35,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -46,7 +48,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Sentry Pro Team', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -59,7 +61,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -72,7 +74,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Pro Team', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: 'annually', baseUnitPrice: 10, benefits: [ @@ -85,7 +87,7 @@ const mockAvailablePlans = [ }, { marketingName: 'Team', - value: 'users-teamm', + value: Plans.USERS_TEAMM, billingRate: 'monthly', baseUnitPrice: 6, benefits: ['Patch coverage analysis'], diff --git a/src/services/account/useAvailablePlans.ts b/src/services/account/useAvailablePlans.ts index 8d92947912..14e0ba3939 100644 --- a/src/services/account/useAvailablePlans.ts +++ b/src/services/account/useAvailablePlans.ts @@ -2,19 +2,16 @@ import { useQuery } from '@tanstack/react-query' import { z } from 'zod' import Api from 'shared/api' +import { Plans } from 'shared/utils/billing' -const IndividualPlanSchema = z - .object({ - baseUnitPrice: z.number(), - benefits: z.array(z.string()), - billingRate: z.string().nullable(), - marketingName: z.string(), - monthlyUploadLimit: z.number().nullable(), - value: z.string(), - }) - .nullable() - -export type IndividualPlan = z.infer +const IndividualPlanSchema = z.object({ + baseUnitPrice: z.number(), + benefits: z.array(z.string()), + billingRate: z.string().nullable(), + marketingName: z.string(), + monthlyUploadLimit: z.number().nullable(), + value: z.nativeEnum(Plans), +}) const PlansSchema = z .object({ diff --git a/src/services/account/useCancelPlan.test.jsx b/src/services/account/useCancelPlan.test.jsx index e2435751de..a780061f27 100644 --- a/src/services/account/useCancelPlan.test.jsx +++ b/src/services/account/useCancelPlan.test.jsx @@ -30,7 +30,7 @@ const accountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 5, - value: 'users-inappm', + value: Plans.USERS_INAPPM, }, activatedUserCount: 2, inactiveUserCount: 1, diff --git a/src/services/account/usePlanData.test.tsx b/src/services/account/usePlanData.test.tsx index ff31b08427..333090e425 100644 --- a/src/services/account/usePlanData.test.tsx +++ b/src/services/account/usePlanData.test.tsx @@ -3,6 +3,8 @@ import { renderHook, waitFor } from '@testing-library/react' import { graphql, HttpResponse } from 'msw' import { setupServer } from 'msw/node' +import { Plans } from 'shared/utils/billing' + import { usePlanData } from './usePlanData' const mockTrialData = { @@ -13,7 +15,7 @@ const mockTrialData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: 'ONGOING', trialStartDate: '2023-01-01T08:55:25', trialEndDate: '2023-01-10T08:55:25', @@ -28,7 +30,7 @@ const mockTrialData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, }, } @@ -86,7 +88,7 @@ describe('usePlanData', () => { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: 'ONGOING', trialStartDate: '2023-01-01T08:55:25', trialEndDate: '2023-01-10T08:55:25', @@ -101,7 +103,7 @@ describe('usePlanData', () => { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, }, }) ) diff --git a/src/services/account/usePlanData.ts b/src/services/account/usePlanData.ts index 0852670af7..1648769d71 100644 --- a/src/services/account/usePlanData.ts +++ b/src/services/account/usePlanData.ts @@ -2,6 +2,7 @@ import { useQuery } from '@tanstack/react-query' import { z } from 'zod' import Api from 'shared/api' +import { Plans } from 'shared/utils/billing' export const TrialStatuses = { NOT_STARTED: 'NOT_STARTED', @@ -16,7 +17,7 @@ const PlanSchema = z.object({ billingRate: z.string().nullable(), marketingName: z.string(), monthlyUploadLimit: z.number().nullable(), - value: z.string(), + value: z.nativeEnum(Plans), pretrialUsersCount: z.number().nullable(), trialEndDate: z.string().nullable(), trialStatus: z.nativeEnum(TrialStatuses), diff --git a/src/services/account/useUpdateBillingAddress.test.tsx b/src/services/account/useUpdateBillingAddress.test.tsx index b8a266b117..4b2e32722e 100644 --- a/src/services/account/useUpdateBillingAddress.test.tsx +++ b/src/services/account/useUpdateBillingAddress.test.tsx @@ -3,6 +3,8 @@ import { renderHook, waitFor } from '@testing-library/react' import { http, HttpResponse } from 'msw' import { setupServer } from 'msw/node' +import { Plans } from 'shared/utils/billing' + import { useUpdateBillingAddress } from './useUpdateBillingAddress' const queryClient = new QueryClient({ @@ -36,7 +38,7 @@ const accountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 5, - value: 'users-inappm', + value: Plans.USERS_PR_INAPPM, }, subscription_detail: { latest_invoice: { diff --git a/src/services/account/useUpdateBillingEmail.test.tsx b/src/services/account/useUpdateBillingEmail.test.tsx index dac81cb586..4151927605 100644 --- a/src/services/account/useUpdateBillingEmail.test.tsx +++ b/src/services/account/useUpdateBillingEmail.test.tsx @@ -3,6 +3,8 @@ import { renderHook, waitFor } from '@testing-library/react' import { http, HttpResponse } from 'msw' import { setupServer } from 'msw/node' +import { Plans } from 'shared/utils/billing' + import { useUpdateBillingEmail } from './useUpdateBillingEmail' const queryClient = new QueryClient({ @@ -36,7 +38,7 @@ const accountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 5, - value: 'users-inappm', + value: Plans.USERS_PR_INAPPM, }, subscription_detail: { latest_invoice: { diff --git a/src/services/account/useUpdateCard.test.tsx b/src/services/account/useUpdateCard.test.tsx index c5c5ede609..fdcc31c7ac 100644 --- a/src/services/account/useUpdateCard.test.tsx +++ b/src/services/account/useUpdateCard.test.tsx @@ -6,6 +6,8 @@ import React from 'react' import { MemoryRouter, Route } from 'react-router-dom' import { type Mock } from 'vitest' +import { Plans } from 'shared/utils/billing' + import { useUpdateCard } from './useUpdateCard' const mocks = vi.hoisted(() => ({ @@ -42,7 +44,7 @@ const accountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 5, - value: 'users-inappm', + value: Plans.USERS_PR_INAPPM, }, activatedUserCount: 2, inactiveUserCount: 1, diff --git a/src/services/account/useUpgradePlan.test.tsx b/src/services/account/useUpgradePlan.test.tsx index 5e11b16427..342edb8cd1 100644 --- a/src/services/account/useUpgradePlan.test.tsx +++ b/src/services/account/useUpgradePlan.test.tsx @@ -5,6 +5,8 @@ import { setupServer } from 'msw/node' import { MemoryRouter, Route } from 'react-router-dom' import type { MockInstance } from 'vitest' +import { Plans } from 'shared/utils/billing' + import { useUpgradePlan } from './useUpgradePlan' const mocks = vi.hoisted(() => ({ @@ -41,7 +43,7 @@ const accountDetails = { baseUnitPrice: 12, benefits: ['Configurable # of users', 'Unlimited repos'], quantity: 5, - value: 'users-inappm', + value: Plans.USERS_PR_INAPPM, }, activatedUserCount: 2, inactiveUserCount: 1, @@ -113,7 +115,7 @@ describe('useUpgradePlan', () => { result.current.mutate({ seats: 12, - newPlan: 'users-pr-inappy', + newPlan: Plans.USERS_PR_INAPPY, }) await waitFor(() => { @@ -147,7 +149,7 @@ describe('useUpgradePlan', () => { result.current.mutate({ seats: 12, - newPlan: 'users-pr-inappy', + newPlan: Plans.USERS_PR_INAPPY, }) await waitFor(() => expect(redirectToCheckout).not.toHaveBeenCalled()) diff --git a/src/services/charts/useSunburstCoverage.ts b/src/services/charts/useSunburstCoverage.ts index 3d1b39a53a..4ab91e054e 100644 --- a/src/services/charts/useSunburstCoverage.ts +++ b/src/services/charts/useSunburstCoverage.ts @@ -1,10 +1,11 @@ import { useQuery } from '@tanstack/react-query' import Api from 'shared/api' +import { Provider } from 'shared/api/helpers' import { providerToInternalProvider } from 'shared/utils' interface SunburstCoverageArgs { - provider: string + provider: Provider owner: string repo: string query?: { diff --git a/src/services/pull/usePull.tsx b/src/services/pull/usePull.tsx index 36a09b487f..e11321b80c 100644 --- a/src/services/pull/usePull.tsx +++ b/src/services/pull/usePull.tsx @@ -186,7 +186,6 @@ export type PullSchemaType = z.infer const RepositorySchema = z.object({ defaultBranch: z.string().nullable(), - private: z.boolean(), __typename: z.literal('Repository'), pull: PullSchema.nullable(), }) @@ -194,7 +193,6 @@ const RepositorySchema = z.object({ const RequestSchema = z.object({ owner: z .object({ - isCurrentUserPartOfOrg: z.boolean(), repository: z.discriminatedUnion('__typename', [ RepositorySchema, RepoNotFoundErrorSchema, @@ -216,7 +214,6 @@ const query = `query Pull( __typename ... on Repository { defaultBranch - private pull(id: $pullId) { behindBy behindByCommit diff --git a/src/shared/GlobalBanners/GitHubRateLimitExceeded/GitHubRateLimitExceededBanner.tsx b/src/shared/GlobalBanners/GitHubRateLimitExceeded/GitHubRateLimitExceededBanner.tsx index a932dca1f4..fb44f94f5c 100644 --- a/src/shared/GlobalBanners/GitHubRateLimitExceeded/GitHubRateLimitExceededBanner.tsx +++ b/src/shared/GlobalBanners/GitHubRateLimitExceeded/GitHubRateLimitExceededBanner.tsx @@ -1,11 +1,12 @@ import { useParams } from 'react-router-dom' +import { Provider } from 'shared/api/helpers' import { providerToName } from 'shared/utils/provider' import A from 'ui/A' import { Alert } from 'ui/Alert' const GitHubRateLimitExceededBanner = () => { - const { provider } = useParams<{ provider: string }>() + const { provider } = useParams<{ provider: Provider }>() const isGh = providerToName(provider) === 'Github' if (!isGh) return null diff --git a/src/shared/GlobalTopBanners/ProPlanFeedbackBanner/ProPlanFeedbackBanner.test.tsx b/src/shared/GlobalTopBanners/ProPlanFeedbackBanner/ProPlanFeedbackBanner.test.tsx index e5183063b4..696ed03121 100644 --- a/src/shared/GlobalTopBanners/ProPlanFeedbackBanner/ProPlanFeedbackBanner.test.tsx +++ b/src/shared/GlobalTopBanners/ProPlanFeedbackBanner/ProPlanFeedbackBanner.test.tsx @@ -8,6 +8,7 @@ import { MemoryRouter, Route } from 'react-router-dom' import { TrialStatuses } from 'services/account' import { TierNames } from 'services/tier' +import { Plans } from 'shared/utils/billing' import ProPlanFeedbackBanner from './ProPlanFeedbackBanner' @@ -27,7 +28,7 @@ const mockTrialData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, trialStatus: TrialStatuses.EXPIRED, trialStartDate: '2023-01-01T08:55:25', trialEndDate: '2023-01-10T08:55:25', @@ -42,7 +43,7 @@ const mockTrialData = { billingRate: 'monthly', marketingName: 'Users Basic', monthlyUploadLimit: 250, - value: 'users-basic', + value: Plans.USERS_BASIC, }, } diff --git a/src/shared/GlobalTopBanners/RequestInstallBanner/RequestInstallBanner.tsx b/src/shared/GlobalTopBanners/RequestInstallBanner/RequestInstallBanner.tsx index 81efca5f72..7b71671920 100644 --- a/src/shared/GlobalTopBanners/RequestInstallBanner/RequestInstallBanner.tsx +++ b/src/shared/GlobalTopBanners/RequestInstallBanner/RequestInstallBanner.tsx @@ -4,6 +4,7 @@ import { useParams, useRouteMatch } from 'react-router-dom' import config from 'config' import { useLocationParams } from 'services/navigation' +import { Provider } from 'shared/api/helpers' import AppInstallModal from 'shared/AppInstallModal' import { providerToName } from 'shared/utils' import Button from 'ui/Button' @@ -13,7 +14,7 @@ import TopBanner, { saveToLocalStorage } from 'ui/TopBanner' const APP_INSTALL_BANNER_KEY = 'request-install-banner' interface URLParams { - provider: string + provider: Provider } const defaultQueryParams = { diff --git a/src/shared/GlobalTopBanners/TrialBanner/TrialBanner.test.tsx b/src/shared/GlobalTopBanners/TrialBanner/TrialBanner.test.tsx index 3208eb2638..40dd200e9a 100644 --- a/src/shared/GlobalTopBanners/TrialBanner/TrialBanner.test.tsx +++ b/src/shared/GlobalTopBanners/TrialBanner/TrialBanner.test.tsx @@ -9,6 +9,7 @@ import { MemoryRouter, Route } from 'react-router-dom' import config from 'config' import { TrialStatuses } from 'services/account' +import { Plans } from 'shared/utils/billing' import TrialBanner from './TrialBanner' @@ -16,7 +17,7 @@ vi.mock('config') const proPlanMonth = { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -33,7 +34,7 @@ const proPlanMonth = { const trialPlan = { marketingName: 'Trial Team', - value: 'users-trial', + value: Plans.USERS_TRIAL, billingRate: 'monthly', baseUnitPrice: 12, benefits: [ @@ -50,7 +51,7 @@ const trialPlan = { const basicPlan = { marketingName: 'Basic', - value: 'users-basic', + value: Plans.USERS_BASIC, billingRate: null, baseUnitPrice: 0, benefits: [ diff --git a/src/shared/api/helpers.ts b/src/shared/api/helpers.ts index 692e810c22..8513756f5f 100644 --- a/src/shared/api/helpers.ts +++ b/src/shared/api/helpers.ts @@ -53,7 +53,7 @@ export const AllProvidersArray = [ 'bitbucket_server', ] as const type AllProviders = typeof AllProvidersArray -type Provider = AllProviders[number] +export type Provider = AllProviders[number] export const ProviderCookieKeyMapping = { gh: 'github-token', diff --git a/src/shared/plan/BenefitList/BenefitList.tsx b/src/shared/plan/BenefitList/BenefitList.tsx index bfa1d99f44..1168dceac2 100644 --- a/src/shared/plan/BenefitList/BenefitList.tsx +++ b/src/shared/plan/BenefitList/BenefitList.tsx @@ -5,7 +5,7 @@ function BenefitList({ iconName, iconColor, }: { - benefits: string[] + benefits?: string[] iconName: string iconColor?: string }) { diff --git a/src/shared/utils/billing.test.js b/src/shared/utils/billing.test.ts similarity index 85% rename from src/shared/utils/billing.test.js rename to src/shared/utils/billing.test.ts index e94d5da10a..61f56a19bd 100644 --- a/src/shared/utils/billing.test.js +++ b/src/shared/utils/billing.test.ts @@ -1,7 +1,5 @@ import { renderHook } from '@testing-library/react' -import { useFlags } from 'shared/featureFlags' - import { canApplySentryUpgrade, EnterprisePlans, @@ -23,20 +21,32 @@ import { isTeamPlan, isTrialPlan, lastTwoDigits, + Plan, Plans, shouldDisplayTeamCard, useProPlans, } from './billing' -vi.mock('shared/featureFlags') +const mocks = vi.hoisted(() => ({ + useFlags: vi.fn(), +})) + +vi.mock('shared/featureFlags', async () => { + const actual = await vi.importActual('shared/featureFlags') + return { + ...actual, + useFlags: mocks.useFlags, + } +}) function getPlans() { return [ { marketingName: 'Basic', - value: 'users-free', + value: Plans.USERS_FREE, billingRate: null, baseUnitPrice: 0, + monthlyUploadLimit: null, benefits: [ 'Up to 5 users', 'Unlimited public repositories', @@ -45,9 +55,10 @@ function getPlans() { }, { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -57,9 +68,10 @@ function getPlans() { }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -69,9 +81,10 @@ function getPlans() { }, { marketingName: 'Pro Team', - value: 'users-enterprisem', + value: Plans.USERS_ENTERPRISEM, billingRate: 'monthly', baseUnitPrice: 12, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -81,9 +94,10 @@ function getPlans() { }, { marketingName: 'Pro Team', - value: 'users-enterprisey', + value: Plans.USERS_ENTERPRISEY, billingRate: 'annually', baseUnitPrice: 10, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -93,9 +107,10 @@ function getPlans() { }, { marketingName: 'Sentry Pro Team', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', baseUnitPrice: 12, + monthlyUploadLimit: null, benefits: [ 'Includes 5 seats', 'Unlimited public repositories', @@ -106,9 +121,10 @@ function getPlans() { }, { marketingName: 'Sentry Pro Team', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, + monthlyUploadLimit: null, benefits: [ 'Includes 5 seats', 'Unlimited public repositories', @@ -119,9 +135,10 @@ function getPlans() { }, { marketingName: 'Team', - value: 'users-teamm', + value: Plans.USERS_TEAMM, billingRate: 'monthly', baseUnitPrice: 6, + monthlyUploadLimit: null, benefits: [ 'Up to 10 users', 'Unlimited repositories', @@ -132,9 +149,10 @@ function getPlans() { }, { marketingName: 'Team', - value: 'users-teamy', + value: Plans.USERS_TEAMY, billingRate: 'yearly', baseUnitPrice: 5, + monthlyUploadLimit: null, benefits: [ 'Up to 10 users', 'Unlimited repositories', @@ -158,11 +176,8 @@ describe('isFreePlan', () => { }) it('Defaults to false otherwise', () => { - expect(isFreePlan('users-pro')).toBe(false) - expect(isFreePlan('rable rable')).toBe(false) + expect(isFreePlan('users-inappy')).toBe(false) expect(isFreePlan(undefined)).toBe(false) - expect(isFreePlan(12345)).toBe(false) - expect(isFreePlan({})).toBe(false) }) }) @@ -176,9 +191,10 @@ describe('shouldDisplayTeamCard', () => { const plans = [ { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -188,9 +204,10 @@ describe('shouldDisplayTeamCard', () => { }, { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -215,17 +232,14 @@ describe('isEnterprisePlans', () => { }) it('defaults to false otherwise', () => { - expect(isEnterprisePlan('users-pro')).toBe(false) - expect(isEnterprisePlan('rable rable')).toBe(false) + expect(isEnterprisePlan('users-inappy')).toBe(false) expect(isEnterprisePlan(undefined)).toBe(false) - expect(isEnterprisePlan(12345)).toBe(false) - expect(isEnterprisePlan({})).toBe(false) }) }) describe('useProPlans', () => { - function setup(flagValue) { - useFlags.mockReturnValue({ + function setup(flagValue: boolean) { + mocks.useFlags.mockReturnValue({ enterpriseCloudPlanSupport: flagValue, }) } @@ -241,9 +255,10 @@ describe('useProPlans', () => { expect(result.current).toEqual({ proPlanMonth: { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -253,9 +268,10 @@ describe('useProPlans', () => { }, proPlanYear: { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -277,9 +293,10 @@ describe('useProPlans', () => { expect(result.current).toEqual({ proPlanMonth: { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -289,9 +306,10 @@ describe('useProPlans', () => { }, proPlanYear: { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -314,6 +332,7 @@ describe('formatNumberToUSD', () => { describe('formatTimestampToCalendarDate', () => { it('formats into calendar date', () => { + // @ts-expect-error const value = formatTimestampToCalendarDate('1660000000') expect(value).toBe('August 8, 2022') @@ -334,6 +353,7 @@ describe('lastTwoDigits', () => { }) it('return null when null', () => { + // @ts-expect-error const value = lastTwoDigits(null) expect(value).toBe(null) @@ -343,16 +363,9 @@ describe('lastTwoDigits', () => { describe('getNextBillingDate', () => { describe('there is a valid timestamp', () => { it('returns formatted timestamp', () => { - const value = getNextBillingDate({}) - - expect(value).toBeNull() - }) - }) - - describe('there is no timestamp', () => { - it('returns null', () => { const value = getNextBillingDate({ subscriptionDetail: { + // @ts-expect-error latestInvoice: { periodEnd: 1660000000, }, @@ -362,6 +375,15 @@ describe('getNextBillingDate', () => { expect(value).toBe('August 8th, 2022') }) }) + + describe('there is no timestamp', () => { + it('returns null', () => { + // @ts-expect-error + const value = getNextBillingDate({}) + + expect(value).toBeNull() + }) + }) }) describe('isAnnualPlan', () => { @@ -386,11 +408,8 @@ describe('isAnnualPlan', () => { }) it('defaults to false otherwise', () => { - expect(isAnnualPlan('users-pro')).toBe(false) - expect(isAnnualPlan('rable rable')).toBe(false) + expect(isAnnualPlan('users-inappm')).toBe(false) expect(isAnnualPlan(undefined)).toBe(false) - expect(isAnnualPlan(12345)).toBe(false) - expect(isAnnualPlan({})).toBe(false) }) }) @@ -411,11 +430,8 @@ describe('isMonthlyPlan', () => { }) it('defaults to false otherwise', () => { - expect(isMonthlyPlan('users-pro')).toBe(false) - expect(isMonthlyPlan('rable rable')).toBe(false) + expect(isMonthlyPlan('users-inappy')).toBe(false) expect(isMonthlyPlan(undefined)).toBe(false) - expect(isMonthlyPlan(12345)).toBe(false) - expect(isMonthlyPlan({})).toBe(false) }) }) @@ -431,11 +447,8 @@ describe('isSentryPlan', () => { }) it('Defaults to false otherwise', () => { - expect(isSentryPlan('users-pro')).toBe(false) - expect(isSentryPlan('rable rable')).toBe(false) + expect(isSentryPlan('users-inappy')).toBe(false) expect(isSentryPlan(undefined)).toBe(false) - expect(isSentryPlan(12345)).toBe(false) - expect(isSentryPlan({})).toBe(false) }) }) @@ -460,10 +473,8 @@ describe('isPaidPlan', () => { }) it('defaults to false otherwise', () => { - expect(isPaidPlan('rable rable')).toBe(false) + expect(isPaidPlan('users-free')).toBe(false) expect(isPaidPlan(undefined)).toBe(false) - expect(isPaidPlan(12345)).toBe(false) - expect(isPaidPlan({})).toBe(false) }) }) @@ -474,9 +485,10 @@ describe('findSentryPlans', () => { const expectedResult = { marketingName: 'Sentry Pro Team', - value: 'users-sentrym', + value: Plans.USERS_SENTRYM, billingRate: 'monthly', baseUnitPrice: 12, + monthlyUploadLimit: null, benefits: [ 'Includes 5 seats', 'Unlimited public repositories', @@ -495,9 +507,10 @@ describe('findSentryPlans', () => { const expectedResult = { marketingName: 'Sentry Pro Team', - value: 'users-sentryy', + value: Plans.USERS_SENTRYY, billingRate: 'annually', baseUnitPrice: 10, + monthlyUploadLimit: null, benefits: [ 'Includes 5 seats', 'Unlimited public repositories', @@ -518,9 +531,10 @@ describe('findProPlans', () => { const expectedResult = { marketingName: 'Pro Team', - value: 'users-pr-inappm', + value: Plans.USERS_PR_INAPPM, billingRate: 'monthly', baseUnitPrice: 12, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -538,9 +552,10 @@ describe('findProPlans', () => { const expectedResult = { marketingName: 'Pro Team', - value: 'users-pr-inappy', + value: Plans.USERS_PR_INAPPY, billingRate: 'annually', baseUnitPrice: 10, + monthlyUploadLimit: null, benefits: [ 'Configureable # of users', 'Unlimited public repositories', @@ -560,9 +575,10 @@ describe('findTeamPlans', () => { const expectedResult = { marketingName: 'Team', - value: 'users-teamm', + value: Plans.USERS_TEAMM, billingRate: 'monthly', baseUnitPrice: 6, + monthlyUploadLimit: null, benefits: [ 'Up to 10 users', 'Unlimited repositories', @@ -581,9 +597,10 @@ describe('findTeamPlans', () => { const expectedResult = { marketingName: 'Team', - value: 'users-teamy', + value: Plans.USERS_TEAMY, billingRate: 'yearly', baseUnitPrice: 5, + monthlyUploadLimit: null, benefits: [ 'Up to 10 users', 'Unlimited repositories', @@ -601,7 +618,7 @@ describe('canApplySentryUpgrade', () => { it('returns true when list contains monthly plan', () => { const result = canApplySentryUpgrade({ plan: Plans.USERS_PR_INAPPM, - plans: [{ value: 'users-sentrym' }], + plans: [{ value: Plans.USERS_SENTRYM }] as Plan[], }) expect(result).toBeTruthy() @@ -610,7 +627,7 @@ describe('canApplySentryUpgrade', () => { it('returns true when list contains annual plan', () => { const result = canApplySentryUpgrade({ plan: Plans.USERS_PR_INAPPM, - plans: [{ value: 'users-sentryy' }], + plans: [{ value: Plans.USERS_SENTRYY }] as Plan[], }) expect(result).toBeTruthy() @@ -619,7 +636,7 @@ describe('canApplySentryUpgrade', () => { it('returns false when plans are not in list', () => { const result = canApplySentryUpgrade({ plan: Plans.USERS_PR_INAPPM, - plans: [{ value: 'users-free' }], + plans: [{ value: Plans.USERS_FREE }] as Plan[], }) expect(result).toBeFalsy() @@ -628,7 +645,7 @@ describe('canApplySentryUpgrade', () => { it('returns false when user has enterprise plan', () => { const result = canApplySentryUpgrade({ plan: Plans.USERS_ENTERPRISEM, - plans: [{ value: 'users-sentryy' }], + plans: [{ value: Plans.USERS_SENTRYY }] as Plan[], }) expect(result).toBeFalsy() @@ -646,12 +663,6 @@ describe('isBasicPlan', () => { expect(isBasicPlan(Plans.USERS_ENTERPRISEM)).toBeFalsy() expect(isBasicPlan(Plans.USERS_SENTRYM)).toBeFalsy() }) - - it('returns false when plan is not a string', () => { - expect(isBasicPlan(123)).toBeFalsy() - expect(isBasicPlan({})).toBeFalsy() - expect(isBasicPlan([])).toBeFalsy() - }) }) describe('isTeamPlan', () => { @@ -667,12 +678,6 @@ describe('isTeamPlan', () => { expect(isTeamPlan(Plans.USERS_ENTERPRISEM)).toBeFalsy() expect(isTeamPlan(Plans.USERS_SENTRYM)).toBeFalsy() }) - - it('returns false when plan is not a string', () => { - expect(isTeamPlan(123)).toBeFalsy() - expect(isTeamPlan({})).toBeFalsy() - expect(isTeamPlan([])).toBeFalsy() - }) }) describe('isTrialPlan', () => { @@ -687,12 +692,6 @@ describe('isTrialPlan', () => { expect(isTrialPlan(Plans.USERS_SENTRYM)).toBeFalsy() expect(isTrialPlan(Plans.USERS_BASIC)).toBeFalsy() }) - - it('returns false when plan is not a string', () => { - expect(isTrialPlan(123)).toBeFalsy() - expect(isTrialPlan({})).toBeFalsy() - expect(isTrialPlan([])).toBeFalsy() - }) }) describe('isProPlan', () => { @@ -709,12 +708,6 @@ describe('isProPlan', () => { expect(isProPlan(Plans.USERS_ENTERPRISEM)).toBeFalsy() expect(isProPlan(Plans.USERS_BASIC)).toBeFalsy() }) - - it('returns false when plan is not a string', () => { - expect(isProPlan(123)).toBeFalsy() - expect(isProPlan({})).toBeFalsy() - expect(isProPlan([])).toBeFalsy() - }) }) describe('isCodecovProPlan', () => { @@ -728,10 +721,4 @@ describe('isCodecovProPlan', () => { expect(isCodecovProPlan(Plans.USERS_SENTRYM)).toBeFalsy() expect(isCodecovProPlan(Plans.USERS_BASIC)).toBeFalsy() }) - - it('returns false when plan is not a string', () => { - expect(isCodecovProPlan(123)).toBeFalsy() - expect(isCodecovProPlan({})).toBeFalsy() - expect(isCodecovProPlan([])).toBeFalsy() - }) }) diff --git a/src/shared/utils/billing.js b/src/shared/utils/billing.ts similarity index 71% rename from src/shared/utils/billing.js rename to src/shared/utils/billing.ts index 814a0c5163..259a1fcdb4 100644 --- a/src/shared/utils/billing.js +++ b/src/shared/utils/billing.ts @@ -2,10 +2,12 @@ import { format, fromUnixTime } from 'date-fns' import isArray from 'lodash/isArray' import isString from 'lodash/isString' import isUndefined from 'lodash/isUndefined' +import { z } from 'zod' +import { AccountDetailsSchema } from 'services/account' import { useFlags } from 'shared/featureFlags' -export const Plans = Object.freeze({ +export const Plans = { USERS_FREE: 'users-free', USERS_BASIC: 'users-basic', USERS_TRIAL: 'users-trial', @@ -19,48 +21,61 @@ export const Plans = Object.freeze({ USERS_TEAMY: 'users-teamy', USERS_ENTERPRISEM: 'users-enterprisem', USERS_ENTERPRISEY: 'users-enterprisey', -}) +} as const + +export type PlanName = (typeof Plans)[keyof typeof Plans] + +export interface Plan { + baseUnitPrice: number + benefits: string[] + billingRate: string | null + marketingName: string + value: PlanName + monthlyUploadLimit: number | null + quantity?: number +} export const EnterprisePlans = Object.freeze({ USERS_ENTERPRISEM: 'users-enterprisem', USERS_ENTERPRISEY: 'users-enterprisey', }) -export function isEnterprisePlan(plan) { +export function isEnterprisePlan(plan?: PlanName | null) { if (isString(plan)) { - return Object.values(EnterprisePlans).includes(plan) + return (Object.values(EnterprisePlans) as string[]).includes(plan) } + return false } -export function isFreePlan(plan) { +export function isFreePlan(plan?: PlanName | null) { if (isString(plan)) { if (plan === Plans.USERS_BASIC || plan === Plans.USERS_FREE) return true } return false } -export function isTeamPlan(plan) { +export function isTeamPlan(plan?: PlanName | null) { if (isString(plan)) { if (plan === Plans.USERS_TEAMM || plan === Plans.USERS_TEAMY) return true } return false } -export function isBasicPlan(plan) { +export function isBasicPlan(plan?: PlanName) { if (isString(plan)) { return plan === Plans.USERS_BASIC } return false } -export function isPaidPlan(plan) { +export function isPaidPlan(plan?: PlanName | null) { if (isString(plan)) { return isAnnualPlan(plan) || isMonthlyPlan(plan) } return false } -export function isMonthlyPlan(plan) { +export function isMonthlyPlan(plan?: PlanName | null) { if (isString(plan)) { return ( plan === Plans.USERS_INAPP || @@ -73,7 +88,7 @@ export function isMonthlyPlan(plan) { return false } -export function isAnnualPlan(plan) { +export function isAnnualPlan(plan?: PlanName | null) { if (isString(plan)) { return ( plan === Plans.USERS_INAPPY || @@ -86,28 +101,28 @@ export function isAnnualPlan(plan) { return false } -export function isSentryPlan(plan) { +export function isSentryPlan(plan?: PlanName | null) { if (isString(plan)) { return plan === Plans.USERS_SENTRYM || plan === Plans.USERS_SENTRYY } return false } -export function isCodecovProPlan(plan) { +export function isCodecovProPlan(plan?: PlanName | null) { if (isString(plan)) { return plan === Plans.USERS_PR_INAPPM || plan === Plans.USERS_PR_INAPPY } return false } -export function isProPlan(plan) { +export function isProPlan(plan?: PlanName | null) { if (isString(plan)) { return isSentryPlan(plan) || isCodecovProPlan(plan) } return false } -export function isTrialPlan(plan) { +export function isTrialPlan(plan?: PlanName | null) { if (isString(plan)) { return plan === Plans.USERS_TRIAL } @@ -120,7 +135,7 @@ export const CollectionMethods = Object.freeze({ AUTOMATICALLY_CHARGED_METHOD: 'charge_automatically', }) -export function useProPlans({ plans }) { +export function useProPlans({ plans }: { plans?: Plan[] | null }) { const { enterpriseCloudPlanSupport } = useFlags({ enterpriseCloudPlanSupport: true, }) @@ -147,7 +162,7 @@ export function useProPlans({ plans }) { } } -export const findProPlans = ({ plans }) => { +export const findProPlans = ({ plans }: { plans?: Plan[] | null }) => { const proPlanMonth = plans?.find( (plan) => plan.value === Plans.USERS_PR_INAPPM ) @@ -161,7 +176,7 @@ export const findProPlans = ({ plans }) => { } } -export const findSentryPlans = ({ plans }) => { +export const findSentryPlans = ({ plans }: { plans?: Plan[] | null }) => { const sentryPlanMonth = plans?.find( (plan) => plan.value === Plans.USERS_SENTRYM ) @@ -175,7 +190,7 @@ export const findSentryPlans = ({ plans }) => { } } -export const findTeamPlans = ({ plans }) => { +export const findTeamPlans = ({ plans }: { plans?: Plan[] | null }) => { const teamPlanMonth = plans?.find((plan) => plan.value === Plans.USERS_TEAMM) const teamPlanYear = plans?.find((plan) => plan.value === Plans.USERS_TEAMY) @@ -185,7 +200,13 @@ export const findTeamPlans = ({ plans }) => { } } -export const canApplySentryUpgrade = ({ plan, plans }) => { +export const canApplySentryUpgrade = ({ + plan, + plans, +}: { + plan?: PlanName + plans?: Plan[] | null +}) => { if (isEnterprisePlan(plan) || !isArray(plans)) { return false } @@ -196,26 +217,30 @@ export const canApplySentryUpgrade = ({ plan, plans }) => { ) } -export const shouldDisplayTeamCard = ({ plans }) => { +export const shouldDisplayTeamCard = ({ plans }: { plans?: Plan[] | null }) => { const { teamPlanMonth, teamPlanYear } = findTeamPlans({ plans }) return !isUndefined(teamPlanMonth) && !isUndefined(teamPlanYear) } -export const formatNumberToUSD = (value) => +export const formatNumberToUSD = (value: number) => Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', currencyDisplay: 'narrowSymbol', }).format(value) -export function getNextBillingDate(accountDetails) { +export function getNextBillingDate( + accountDetails?: z.infer | null +) { const timestamp = accountDetails?.subscriptionDetail?.latestInvoice?.periodEnd return timestamp ? format(fromUnixTime(timestamp), 'MMMM do, yyyy') : null } // TODO: This is now the preferred format for dates, please use this over any other formatting -export function formatTimestampToCalendarDate(timestamp) { +export function formatTimestampToCalendarDate( + timestamp: number | null | undefined +) { if (!timestamp) { return null } @@ -226,10 +251,11 @@ export function formatTimestampToCalendarDate(timestamp) { day: 'numeric', year: 'numeric', } + // @ts-expect-error Complaining about year not being type 'numeric' | '2-digit' | 'undefined' return new Intl.DateTimeFormat('en-US', options).format(date) } -export function lastTwoDigits(value) { +export function lastTwoDigits(value: number | string) { if (typeof value === 'number' || typeof value === 'string') { return value.toString().slice(-2) } diff --git a/src/shared/utils/provider.test.js b/src/shared/utils/provider.test.ts similarity index 70% rename from src/shared/utils/provider.test.js rename to src/shared/utils/provider.test.ts index 5a7e284b8e..18d2328233 100644 --- a/src/shared/utils/provider.test.js +++ b/src/shared/utils/provider.test.ts @@ -3,8 +3,6 @@ import config from 'config' import { getProviderCommitURL, getProviderPullURL, - providerFeedback, - providerImage, providerToInternalProvider, providerToName, } from './provider' @@ -62,6 +60,7 @@ describe('providerToName', () => { describe('when called with BitBucket', () => { it('returns BitBucket', () => { + // @ts-expect-error expect(providerToName('BitBucket')).toBe('BitBucket') }) }) @@ -85,88 +84,10 @@ describe('providerToName', () => { }) }) -describe('providerImage', () => { - describe('when called for Github', () => { - it('returns correct logo url', () => { - expect(providerImage('Github')).toMatch(/github-icon.svg/) - }) - }) - describe('when called for Gitlab', () => { - it('returns correct logo url', () => { - expect(providerImage('Gitlab')).toMatch(/gitlab-icon.svg/) - }) - }) - describe('when called for BitBucket', () => { - it('returns correct logo url', () => { - expect(providerImage('BitBucket')).toMatch(/bitbucket-icon.svg/) - }) - }) - describe('when called for Github Enterprise', () => { - it('returns correct logo url', () => { - expect(providerImage('github_enterprise')).toMatch(/github-icon.svg/) - }) - }) - describe('when called for Gitlab Enterprise', () => { - it('returns correct logo url', () => { - expect(providerImage('gitlab_enterprise')).toMatch(/gitlab-icon.svg/) - }) - }) - describe('when called for BitBucket Server', () => { - it('returns correct logo url', () => { - expect(providerImage('bitbucket_server')).toMatch(/bitbucket-icon.svg/) - }) - }) -}) - -describe('providerFeedback', () => { - describe('when called for Github', () => { - it('returns correct url', () => { - expect(providerFeedback('Github')).toEqual( - 'https://github.com/codecov/Codecov-user-feedback/issues/1' - ) - }) - }) - describe('when called for Gitlab', () => { - it('returns correct url', () => { - expect(providerFeedback('Gitlab')).toEqual( - 'https://gitlab.com/codecov-open-source/codecov-user-feedback/-/issues/1' - ) - }) - }) - describe('when called for BitBucket', () => { - it('returns correct url', () => { - expect(providerFeedback('BitBucket')).toEqual( - 'https://bitbucket.org/kylemann/codecov/issues/1/wed-love-your-feedback' - ) - }) - }) - describe('when called for Github Enterprise', () => { - it('returns correct url', () => { - expect(providerFeedback('github_enterprise')).toEqual( - 'https://github.com/codecov/Codecov-user-feedback/issues/1' - ) - }) - }) - describe('when called for Gitlab Enterprise', () => { - it('returns correct url', () => { - expect(providerFeedback('gitlab_enterprise')).toEqual( - 'https://gitlab.com/codecov-open-source/codecov-user-feedback/-/issues/1' - ) - }) - }) - describe('when called for BitBucket Server', () => { - it('returns correct url', () => { - expect(providerFeedback('bitbucket_server')).toEqual( - 'https://bitbucket.org/kylemann/codecov/issues/1/wed-love-your-feedback' - ) - }) - }) -}) - const repo = 'python' const owner = 'codecov' const commit = '12de' -const pullId = 'aebf' +const pullId = 12 describe('getProviderCommitURL', () => { it('return gitlab commit URL', () => { @@ -210,38 +131,38 @@ describe('getProviderCommitURL', () => { describe('getProviderPullURL', () => { it('return gitlab PR URL', () => { expect(getProviderPullURL({ provider: 'gl', owner, repo, pullId })).toBe( - 'https://gitlab.com/codecov/python/-/merge_requests/aebf' + 'https://gitlab.com/codecov/python/-/merge_requests/12' ) }) it('return github PR URL', () => { expect(getProviderPullURL({ provider: 'gh', owner, repo, pullId })).toBe( - 'https://github.com/codecov/python/pull/aebf' + 'https://github.com/codecov/python/pull/12' ) }) it('return bb PR URL', () => { expect(getProviderPullURL({ provider: 'bb', owner, repo, pullId })).toBe( - 'https://bitbucket.org/codecov/python/pull-requests/aebf' + 'https://bitbucket.org/codecov/python/pull-requests/12' ) }) it('return ghe PR URL', () => { config.GHE_URL = 'https://github.mycompany.org' expect(getProviderPullURL({ provider: 'ghe', owner, repo, pullId })).toBe( - 'https://github.mycompany.org/codecov/python/pull/aebf' + 'https://github.mycompany.org/codecov/python/pull/12' ) }) it('return gle PR URL', () => { config.GLE_URL = 'https://gitlab.mycompany.org' expect(getProviderPullURL({ provider: 'gle', owner, repo, pullId })).toBe( - 'https://gitlab.mycompany.org/codecov/python/-/merge_requests/aebf' + 'https://gitlab.mycompany.org/codecov/python/-/merge_requests/12' ) }) it('return bbs PR URL', () => { config.BBS_URL = 'https://bitbucket.mycompany.org' expect(getProviderPullURL({ provider: 'bbs', owner, repo, pullId })).toBe( - 'https://bitbucket.mycompany.org/codecov/python/pull-requests/aebf' + 'https://bitbucket.mycompany.org/codecov/python/pull-requests/12' ) }) }) @@ -297,6 +218,7 @@ describe('providerToInternalProvider', () => { describe('when called with BitBucket', () => { it('returns bitbucket', () => { + // @ts-expect-error expect(providerToInternalProvider('BitBucket')).toBe('bitbucket') }) }) diff --git a/src/shared/utils/provider.js b/src/shared/utils/provider.ts similarity index 57% rename from src/shared/utils/provider.js rename to src/shared/utils/provider.ts index 654ebe3ec3..56c2d3499c 100644 --- a/src/shared/utils/provider.js +++ b/src/shared/utils/provider.ts @@ -1,11 +1,9 @@ /* eslint-disable camelcase */ import config from 'config' -import bitbucketLogo from 'assets/providers/bitbucket-icon.svg' -import githubLogo from 'assets/providers/github-icon.svg' -import gitlabLogo from 'assets/providers/gitlab-icon.svg' +import { Provider } from 'shared/api/helpers' -export function providerToName(provider) { +export function providerToName(provider: Provider) { return { gh: 'Github', bb: 'BitBucket', @@ -22,7 +20,7 @@ export function providerToName(provider) { }[provider.toLowerCase()] } -export function providerToInternalProvider(provider) { +export function providerToInternalProvider(provider: Provider) { return { gh: 'github', bb: 'bitbucket', @@ -39,34 +37,17 @@ export function providerToInternalProvider(provider) { }[provider.toLowerCase()] } -export function providerImage(providerName) { - return { - Github: githubLogo, - Gitlab: gitlabLogo, - BitBucket: bitbucketLogo, - 'Github Enterprise': githubLogo, - 'Gitlab Enterprise': gitlabLogo, - 'BitBucket Server': bitbucketLogo, - }[providerToName(providerName)] -} - -export function providerFeedback(providerName) { - return { - Github: 'https://github.com/codecov/Codecov-user-feedback/issues/1', - Gitlab: - 'https://gitlab.com/codecov-open-source/codecov-user-feedback/-/issues/1', - BitBucket: - 'https://bitbucket.org/kylemann/codecov/issues/1/wed-love-your-feedback', - 'Github Enterprise': - 'https://github.com/codecov/Codecov-user-feedback/issues/1', - 'Gitlab Enterprise': - 'https://gitlab.com/codecov-open-source/codecov-user-feedback/-/issues/1', - 'BitBucket Server': - 'https://bitbucket.org/kylemann/codecov/issues/1/wed-love-your-feedback', - }[providerToName(providerName)] -} - -export function getProviderCommitURL({ provider, owner, repo, commit }) { +export function getProviderCommitURL({ + provider, + owner, + repo, + commit, +}: { + provider: Provider + owner: string + repo: string + commit: string +}) { return { Github: `https://github.com/${owner}/${repo}/commit/${commit}`, BitBucket: `https://bitbucket.org/${owner}/${repo}/commits/${commit}`, @@ -74,10 +55,21 @@ export function getProviderCommitURL({ provider, owner, repo, commit }) { 'Github Enterprise': `${config.GHE_URL}/${owner}/${repo}/commit/${commit}`, 'Gitlab Enterprise': `${config.GLE_URL}/${owner}/${repo}/-/commit/${commit}`, 'BitBucket Server': `${config.BBS_URL}/${owner}/${repo}/commits/${commit}`, + // @ts-expect-error }[providerToName(provider)] } -export function getProviderPullURL({ provider, owner, repo, pullId }) { +export function getProviderPullURL({ + provider, + owner, + repo, + pullId, +}: { + provider: Provider + owner: string + repo: string + pullId: number +}) { return { Github: `https://github.com/${owner}/${repo}/pull/${pullId}`, BitBucket: `https://bitbucket.org/${owner}/${repo}/pull-requests/${pullId}`, @@ -85,5 +77,6 @@ export function getProviderPullURL({ provider, owner, repo, pullId }) { 'Github Enterprise': `${config.GHE_URL}/${owner}/${repo}/pull/${pullId}`, 'Gitlab Enterprise': `${config.GLE_URL}/${owner}/${repo}/-/merge_requests/${pullId}`, 'BitBucket Server': `${config.BBS_URL}/${owner}/${repo}/pull-requests/${pullId}`, + // @ts-expect-error }[providerToName(provider)] } diff --git a/src/shared/utils/upgradeForm.test.js b/src/shared/utils/upgradeForm.test.js index 0e359a9f91..f56aec08a7 100644 --- a/src/shared/utils/upgradeForm.test.js +++ b/src/shared/utils/upgradeForm.test.js @@ -149,7 +149,7 @@ describe('getDefaultValuesUpgradeForm', () => { }) expect(data).toStrictEqual({ - newPlan: 'users-teamm', + newPlan: Plans.USERS_TEAMM, seats: 2, }) })