Skip to content

Commit 1d013b3

Browse files
authored
feat: add zuora outage page and panel (#2914)
* feat: add zuora outage page and panel * chore: change to absolute imports * chore: add tests * chore: added ternary operator
1 parent 730f663 commit 1d013b3

File tree

7 files changed

+286
-4
lines changed

7 files changed

+286
-4
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import {Organization} from 'src/types'
2+
3+
describe('Billing Page Free Users', () => {
4+
beforeEach(() =>
5+
cy.flush().then(() =>
6+
cy.signin().then(() => {
7+
cy.get('@org').then(() => {
8+
cy.setFeatureFlags({
9+
quartzZuoraDisabled: true,
10+
}).then(() => {
11+
cy.quartzProvision({
12+
accountType: 'free',
13+
}).then(() => {
14+
cy.visit(`/checkout`)
15+
})
16+
})
17+
})
18+
})
19+
)
20+
)
21+
22+
it('should display the zuora outage page', () => {
23+
cy.getByTestID('zuora-outage--panel').should('be.visible')
24+
})
25+
})
26+
27+
describe('Billing Page PAYG Users', () => {
28+
beforeEach(() =>
29+
cy.flush().then(() =>
30+
cy.signin().then(() => {
31+
cy.get('@org').then(({id}: Organization) => {
32+
cy.setFeatureFlags({
33+
uiUnificationFlag: true,
34+
quartzZuoraDisabled: true,
35+
}).then(() => {
36+
cy.quartzProvision({
37+
accountType: 'pay_as_you_go',
38+
}).then(() => {
39+
cy.visit(`/orgs/${id}/billing`)
40+
cy.getByTestID('billing-page--header').should('be.visible')
41+
})
42+
})
43+
})
44+
})
45+
)
46+
)
47+
48+
it('should display the zuora outage panel', () => {
49+
// The implication here is that there is no Upgrade Now button
50+
cy.get('.cf-page-header--fixed')
51+
.children()
52+
.should('have.length', 1)
53+
54+
// PAYG section
55+
cy.getByTestID('payg-plan--header').contains('Pay As You Go')
56+
cy.getByTestID('payg-plan--region-header').contains('Region')
57+
cy.getByTestID('payg-plan--region-body').contains('aws')
58+
59+
cy.getByTestID('payg-plan--balance-header').contains('Account Balance')
60+
cy.getByTestID('payg-plan--balance-body').contains('10.00')
61+
62+
cy.getByTestID('payg-plan--updated-header').contains('Last Update')
63+
cy.getByTestID('payg-plan--updated-body').contains(
64+
`${new Date().toLocaleString('default', {
65+
month: 'numeric',
66+
day: 'numeric',
67+
year: 'numeric',
68+
hour: 'numeric',
69+
minute: '2-digit',
70+
})}`
71+
)
72+
73+
// Invoices Section
74+
cy.getByTestID('past-invoices--header').contains('Past Invoices')
75+
cy.getByTestID('invoice-history--row').should('have.length', 2)
76+
77+
cy.getByTestID('invoice-history--name')
78+
.last()
79+
.contains('December 2020 Invoice')
80+
cy.getByTestID('invoice-history--amount')
81+
.last()
82+
.contains('$100.00')
83+
cy.getByTestID('invoice-history--status')
84+
.last()
85+
.contains('unpaid')
86+
87+
// Sort by date
88+
cy.getByTestID('invoice-date--sorter')
89+
.contains('Invoice Date')
90+
.click()
91+
92+
// Should now be the first item
93+
cy.getByTestID('invoice-history--name')
94+
.first()
95+
.contains('December 2020 Invoice')
96+
97+
// Sort by amount
98+
cy.getByTestID('invoice-amount--sorter')
99+
.contains('Amount')
100+
.click()
101+
102+
cy.getByTestID('invoice-history--amount')
103+
.first()
104+
.contains('$10.00')
105+
106+
cy.getByTestID('invoice-status--sorter')
107+
.contains('Status')
108+
.click()
109+
110+
cy.getByTestID('invoice-history--status')
111+
.first()
112+
.contains('paid')
113+
114+
// Payment Method Section should render Zuora Outage Panel instead
115+
cy.getByTestID('zuora-outage--panel').should('be.visible')
116+
117+
// Contact Information Section
118+
cy.getByTestID('billing-contact--header').contains('Contact Information')
119+
cy.getByTestID('form-label--First Name').contains('First Name')
120+
cy.getByTestID('contact-info--Test').contains('Test')
121+
cy.getByTestID('form-label--Last Name').contains('Last Name')
122+
cy.getByTestID('contact-info--PAYG').contains('PAYG')
123+
cy.getByTestID('form-label--Company Name').contains('Company Name')
124+
cy.getByTestID('contact-info--InfluxData').contains('InfluxData')
125+
cy.getByTestID('form-label--Country').contains('Country')
126+
cy.getByTestID('contact-info--USA').contains('USA')
127+
cy.getByTestID('form-label--Physical Address').contains('Physical Address')
128+
cy.getByTestID('contact-info--123 Main St, Apt 2').contains(
129+
'123 Main St, Apt 2'
130+
)
131+
cy.getByTestID('form-label--City').contains('City')
132+
cy.getByTestID('contact-info--Los Angeles').contains('Los Angeles')
133+
cy.getByTestID('form-label--State (Subdivision)').contains(
134+
'State (Subdivision)'
135+
)
136+
cy.getByTestID('contact-info--California').contains('California')
137+
cy.getByTestID('form-label--Postal Code').contains('Postal Code')
138+
cy.getByTestID('contact-info--90001').contains('90001')
139+
140+
// Click the edit information button
141+
cy.getByTestID('edit-contact--button')
142+
.contains('Edit Information')
143+
.click()
144+
cy.getByTestID('form-input--firstname')
145+
.clear()
146+
.type('Salt')
147+
cy.getByTestID('form-input--lastname')
148+
.clear()
149+
.type('Bae')
150+
cy.getByTestID('save-contact--button').click()
151+
152+
// Validate that the first and last name are updated
153+
cy.getByTestID('contact-info--Salt')
154+
.contains('Salt')
155+
.and('not.be', 'Test')
156+
cy.getByTestID('contact-info--Bae')
157+
.contains('Bae')
158+
.and('not.be', 'PAYG')
159+
160+
// Notification Settings Section
161+
cy.getByTestID('notification-settings--header').contains(
162+
'Notification Settings'
163+
)
164+
cy.getByTestID('billing-settings--text').contains('test@influxdata.com')
165+
cy.getByTestID('billing-settings--text').contains('$11')
166+
cy.getByTestID('notification-settings--button').click()
167+
168+
// Toggle the settings off
169+
cy.getByTestID('should-notify--toggle').click()
170+
cy.getByTestID('save-settings--button').click()
171+
cy.getByTestID('billing-settings--text').contains(
172+
'Usage Notifications disabled'
173+
)
174+
175+
// Notification Settings Section
176+
cy.getByTestID('cancel-service--header').contains('Cancel Service')
177+
cy.getByTestID('cancel-service--button').click()
178+
cy.getByTestID('cancel-overlay--alert').contains(
179+
'This action cannot be undone'
180+
)
181+
// check that the button is disabled
182+
cy.getByTestID('cancel-service-confirmation--button').should('be.disabled')
183+
cy.getByTestID('agree-terms--checkbox').should('not.be.checked')
184+
185+
cy.getByTestID('agree-terms--input').click()
186+
cy.getByTestID('agree-terms--checkbox').should('be.checked')
187+
cy.getByTestID('cancel-service-confirmation--button')
188+
.should('not.be.disabled')
189+
.click()
190+
191+
// TLDR; we double confirm here, this is by design. The overlay changes to reflect a new state so this isn't an error in the test
192+
cy.getByTestID('cancel-service-confirmation--button').click()
193+
})
194+
})

src/billing/components/PaymentInfo/PaymentPanel.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import React, {FC, useContext, useState} from 'react'
33

44
// Components
55
import {Panel} from '@influxdata/clockface'
6-
import PaymentPanelHeader from './PaymentPanelHeader'
7-
import PaymentPanelBody from './PaymentPanelBody'
6+
import PaymentPanelHeader from 'src/billing/components/PaymentInfo/PaymentPanelHeader'
7+
import PaymentPanelBody from 'src/billing/components/PaymentInfo/PaymentPanelBody'
88
import {BillingContext} from 'src/billing/context/billing'
9+
import ZuoraOutagePanel from 'src/shared/components/zuora/ZuoraOutagePanel'
10+
import {isFlagEnabled} from 'src/shared/utils/featureFlag'
911

1012
const PaymentPanel: FC = () => {
1113
const {
@@ -34,7 +36,9 @@ const PaymentPanel: FC = () => {
3436
}
3537
}
3638

37-
return (
39+
return isFlagEnabled('quartzZuoraDisabled') ? (
40+
<ZuoraOutagePanel />
41+
) : (
3842
<Panel className="checkout-panel payment-method-panel">
3943
<PaymentPanelHeader
4044
onEdit={onEdit}

src/checkout/CheckoutPage.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@ import React, {FC} from 'react'
44
import CheckoutForm from 'src/checkout/CheckoutForm'
55
import SuccessOverlay from 'src/checkout/SuccessOverlay'
66
import CheckoutProvider from 'src/checkout/context/checkout'
7+
import {isFlagEnabled} from 'src/shared/utils/featureFlag'
8+
import ZuoraOutagePage from 'src/shared/components/zuora/ZuoraOutagePage'
79

810
const CheckoutV2: FC = () => {
911
return (
1012
<CheckoutProvider>
1113
<>
1214
<SuccessOverlay />
13-
<CheckoutForm />
15+
{isFlagEnabled('quartzZuoraDisabled') ? (
16+
<ZuoraOutagePage />
17+
) : (
18+
<CheckoutForm />
19+
)}
1420
</>
1521
</CheckoutProvider>
1622
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.zuora-outage-funnel-page {
2+
.cf-funnel-page--content {
3+
display: flex;
4+
align-items: center;
5+
justify-content: center;
6+
flex-direction: column;
7+
8+
> .zuora-outage-panel {
9+
margin: 50px;
10+
font-size: large;
11+
}
12+
}
13+
}
14+
15+
.zuora-outage-panel {
16+
font-size: larger;
17+
> .zuora-outage-panel-body {
18+
text-align: left;
19+
}
20+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Libraries
2+
import React, {FC} from 'react'
3+
import {FunnelPage} from '@influxdata/clockface'
4+
import LogoWithCubo from 'src/checkout/LogoWithCubo'
5+
import ZuoraOutagePanel from 'src/shared/components/zuora/ZuoraOutagePanel'
6+
7+
// Components
8+
9+
// Types
10+
11+
// Constants
12+
13+
const ZuoraOutagePage: FC = () => {
14+
return (
15+
<FunnelPage
16+
logo={<LogoWithCubo />}
17+
enableGraphic={true}
18+
className="zuora-outage-funnel-page"
19+
>
20+
<ZuoraOutagePanel />
21+
</FunnelPage>
22+
)
23+
}
24+
25+
export default ZuoraOutagePage
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Libraries
2+
import React, {FC} from 'react'
3+
import {Panel} from '@influxdata/clockface'
4+
5+
// Components
6+
7+
// Types
8+
9+
// Constants
10+
11+
const ZuoraOutagePanel: FC = () => {
12+
return (
13+
<Panel className="zuora-outage-panel" testID="zuora-outage--panel">
14+
<Panel.Header>Sorry!</Panel.Header>
15+
<Panel.Body className="zuora-outage-panel-body">
16+
Our billing system is currently unavailable due to planned maintenance
17+
or unexpected downtime by our payment provider.
18+
<br />
19+
<br />
20+
<div>
21+
Please check back later or visit our{' '}
22+
<a target="_blank" href="https://status.influxdata.com/">
23+
status page
24+
</a>{' '}
25+
for more detail on when our payment system will be back online.
26+
</div>
27+
</Panel.Body>
28+
</Panel>
29+
)
30+
}
31+
32+
export default ZuoraOutagePanel

src/style/chronograf.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
@import 'src/alerting/components/AlertHistoryIndex.scss';
113113
@import 'src/alerting/components/LevelTableField.scss';
114114
@import 'src/alerting/components/SentTableField.scss';
115+
@import 'src/shared/components/zuora/ZuoraOutagePage.scss';
115116
@import 'src/notifications/rules/components/RuleOverlayFooter.scss';
116117
@import 'src/labels/components/LabelCard.scss';
117118
@import 'src/alerting/components/SearchBar.scss';

0 commit comments

Comments
 (0)