Skip to content

Commit e28f4fa

Browse files
fix: Only allow error banner to switch to yearly if already yearly
1 parent 7bde0ec commit e28f4fa

File tree

6 files changed

+122
-14
lines changed

6 files changed

+122
-14
lines changed

src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/ProPlanController/BillingOptions/BillingOptions.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,17 @@ const BillingControls: React.FC<BillingControlsProps> = ({
9696
</RadioTileGroup.Item>
9797
</RadioTileGroup>
9898
<p>
99-
<span className="font-semibold">${baseUnitPrice}</span> per
100-
seat/month, billed {billingRate}
99+
{baseUnitPrice !== undefined && (
100+
<>
101+
<span className="font-semibold">${baseUnitPrice}</span> per
102+
seat/month
103+
</>
104+
)}
105+
{billingRate && (
106+
<>
107+
{baseUnitPrice !== undefined && ', '}billed {billingRate}
108+
</>
109+
)}
101110
</p>
102111
</div>
103112
</div>

src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/SentryPlanController/BillingOptions/BillingOptions.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,17 @@ const BillingControls: React.FC<BillingControlsProps> = ({
9797
</RadioTileGroup.Item>
9898
</RadioTileGroup>
9999
<p>
100-
<span className="font-semibold">${baseUnitPrice}</span> per
101-
seat/month, billed {billingRate}
100+
{baseUnitPrice !== undefined && (
101+
<>
102+
<span className="font-semibold">${baseUnitPrice}</span> per
103+
seat/month
104+
</>
105+
)}
106+
{billingRate && (
107+
<>
108+
{baseUnitPrice !== undefined && ', '}billed {billingRate}
109+
</>
110+
)}
102111
</p>
103112
</div>
104113
</div>

src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/BillingOptions/BillingOptions.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,17 @@ const BillingControls: React.FC<BillingControlsProps> = ({
9696
</RadioTileGroup.Item>
9797
</RadioTileGroup>
9898
<p>
99-
<span className="font-semibold">${baseUnitPrice}</span> per
100-
seat/month, billed {billingRate}
99+
{baseUnitPrice !== undefined && (
100+
<>
101+
<span className="font-semibold">${baseUnitPrice}</span> per
102+
seat/month
103+
</>
104+
)}
105+
{billingRate && (
106+
<>
107+
{baseUnitPrice !== undefined && ', '}billed {billingRate}
108+
</>
109+
)}
101110
</p>
102111
</div>
103112
</div>

src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/ErrorBanner/ErrorBanner.test.tsx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@ const teamPlanYear = {
5252
isSentryPlan: false,
5353
}
5454

55+
const proPlanMonth = {
56+
value: Plans.USERS_PR_INAPPM,
57+
baseUnitPrice: 12,
58+
benefits: ['asdf'],
59+
billingRate: BillingRate.MONTHLY,
60+
marketingName: 'Users Pro',
61+
monthlyUploadLimit: null,
62+
hasSeatsLeft: true,
63+
isTeamPlan: false,
64+
isSentryPlan: false,
65+
}
66+
5567
const proPlanYear = {
5668
value: Plans.USERS_PR_INAPPY,
5769
baseUnitPrice: 10,
@@ -126,6 +138,7 @@ describe('ErrorBanner', () => {
126138
basicPlan,
127139
teamPlanMonth,
128140
teamPlanYear,
141+
proPlanMonth,
129142
proPlanYear,
130143
],
131144
},
@@ -215,7 +228,7 @@ describe('ErrorBanner', () => {
215228
})
216229

217230
describe('and user clicks Upgrade to Pro button', () => {
218-
it('updates selected plan', async () => {
231+
it('updates selected plan to monthly when current plan is monthly', async () => {
219232
const { user } = setup({ planValue: Plans.USERS_TEAMM })
220233
render(<ErrorBanner {...props} />, { wrapper: wrapper() })
221234

@@ -226,6 +239,27 @@ describe('ErrorBanner', () => {
226239

227240
await user.click(button)
228241

242+
expect(props.setSelectedPlan).toHaveBeenCalledWith(
243+
expect.objectContaining({ value: Plans.USERS_PR_INAPPM })
244+
)
245+
expect(props.setFormValue).toHaveBeenCalledWith(
246+
'newPlan',
247+
{ ...proPlanMonth, hasSeatsLeft: undefined },
248+
{ shouldValidate: true }
249+
)
250+
})
251+
252+
it('updates selected plan to yearly when current plan is yearly', async () => {
253+
const { user } = setup({ planValue: Plans.USERS_TEAMY })
254+
render(<ErrorBanner {...props} />, { wrapper: wrapper() })
255+
256+
const button = await screen.findByRole('button', {
257+
name: 'Upgrade to Pro',
258+
})
259+
expect(button).toBeInTheDocument()
260+
261+
await user.click(button)
262+
229263
expect(props.setSelectedPlan).toHaveBeenCalledWith(
230264
expect.objectContaining({ value: Plans.USERS_PR_INAPPY })
231265
)

src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/ErrorBanner/ErrorBanner.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
import { usePlanData } from 'services/account/usePlanData'
99
import { useLocationParams } from 'services/navigation/useLocationParams'
1010
import {
11+
BillingRate,
1112
canApplySentryUpgrade,
1213
findProPlans,
1314
findSentryPlans,
@@ -38,13 +39,22 @@ export default function ErrorBanner({
3839
const { updateParams } = useLocationParams({ plan: null })
3940
const { data: plans } = useAvailablePlans({ provider, owner })
4041
const { data: planData } = usePlanData({ provider, owner })
41-
const { proPlanYear } = findProPlans({ plans })
42-
const { sentryPlanYear } = findSentryPlans({ plans })
42+
const { proPlanYear, proPlanMonth } = findProPlans({ plans })
43+
const { sentryPlanYear, sentryPlanMonth } = findSentryPlans({ plans })
4344
const isSentryUpgrade = canApplySentryUpgrade({
4445
isEnterprisePlan: planData?.plan?.isEnterprisePlan,
4546
plans,
4647
})
47-
const yearlyProPlan = isSentryUpgrade ? sentryPlanYear : proPlanYear
48+
const isYearlyPlan = planData?.plan?.billingRate === BillingRate.ANNUALLY
49+
50+
// Only show yearly plan if current plan is yearly
51+
const proPlan = isYearlyPlan
52+
? isSentryUpgrade
53+
? sentryPlanYear
54+
: proPlanYear
55+
: isSentryUpgrade
56+
? sentryPlanMonth
57+
: proPlanMonth
4858

4959
if (errors?.seats?.message === UPGRADE_FORM_TOO_MANY_SEATS_MESSAGE) {
5060
return (
@@ -56,8 +66,8 @@ export default function ErrorBanner({
5666
<button
5767
className="cursor-pointer font-semibold text-ds-blue-darker hover:underline"
5868
onClick={() => {
59-
setSelectedPlan(yearlyProPlan)
60-
setFormValue('newPlan', yearlyProPlan, {
69+
setSelectedPlan(proPlan)
70+
setFormValue('newPlan', proPlan, {
6171
shouldValidate: true,
6272
})
6373
// without this line, the tier selector won't update

src/pages/PlanPage/subRoutes/UpgradePlanPage/UpgradeForm/Controllers/TeamPlanController/TeamPlanController.test.tsx

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,17 @@ const teamPlanYear = {
6464
isSentryPlan: false,
6565
}
6666

67+
const proPlanMonth = {
68+
value: Plans.USERS_PR_INAPPM,
69+
baseUnitPrice: 12,
70+
benefits: ['asdf'],
71+
billingRate: BillingRate.MONTHLY,
72+
marketingName: 'Users Pro',
73+
monthlyUploadLimit: null,
74+
isTeamPlan: false,
75+
isSentryPlan: false,
76+
}
77+
6778
const proPlanYear = {
6879
value: Plans.USERS_PR_INAPPY,
6980
baseUnitPrice: 10,
@@ -228,6 +239,7 @@ describe('TeamPlanController', () => {
228239
basicPlan,
229240
teamPlanMonth,
230241
teamPlanYear,
242+
proPlanMonth,
231243
proPlanYear,
232244
],
233245
},
@@ -344,8 +356,33 @@ describe('TeamPlanController', () => {
344356
})
345357

346358
describe('and user clicks Upgrade to Pro button', () => {
347-
it('updates selected plan', async () => {
348-
const { user } = setup({ planValue: Plans.USERS_TEAMM })
359+
it('updates selected plan when current plan is monthly', async () => {
360+
const { user } = setup({
361+
planValue: Plans.USERS_TEAMM,
362+
monthlyPlan: true,
363+
})
364+
render(<TeamPlanController {...props} />, { wrapper: wrapper() })
365+
366+
const button = await screen.findByRole('button', {
367+
name: 'Upgrade to Pro',
368+
})
369+
expect(button).toBeInTheDocument()
370+
371+
await user.click(button)
372+
373+
expect(setSelectedPlan).toHaveBeenCalledWith(
374+
expect.objectContaining({ value: Plans.USERS_PR_INAPPM })
375+
)
376+
expect(setFormValue).toHaveBeenCalledWith('newPlan', proPlanMonth, {
377+
shouldValidate: true,
378+
})
379+
})
380+
381+
it('updates selected plan when current plan is yearly', async () => {
382+
const { user } = setup({
383+
planValue: Plans.USERS_TEAMY,
384+
monthlyPlan: false,
385+
})
349386
render(<TeamPlanController {...props} />, { wrapper: wrapper() })
350387

351388
const button = await screen.findByRole('button', {

0 commit comments

Comments
 (0)