Skip to content

Commit 2dd7727

Browse files
new changes
Signed-off-by: Adhitya Mamallan <adhitya.mamallan@uber.com>
1 parent 3a34dd1 commit 2dd7727

File tree

7 files changed

+604
-27
lines changed

7 files changed

+604
-27
lines changed
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
import { render, screen } from '@/test-utils/rtl';
2+
3+
import * as usePageQueryParamsModule from '@/hooks/use-page-query-params/use-page-query-params';
4+
import { type FailoverEvent } from '@/route-handlers/list-failover-history/list-failover-history.types';
5+
import { mockDomainPageQueryParamsValues } from '@/views/domain-page/__fixtures__/domain-page-query-params';
6+
import { PRIMARY_CLUSTER_SCOPE } from '@/views/domain-page/domain-page-failovers/domain-page-failovers.constants';
7+
8+
import DomainPageFailoverActiveActive from '../domain-page-failover-active-active';
9+
10+
const mockSetQueryParams = jest.fn();
11+
jest.mock('@/hooks/use-page-query-params/use-page-query-params', () =>
12+
jest.fn(() => [mockDomainPageQueryParamsValues, mockSetQueryParams])
13+
);
14+
15+
jest.mock(
16+
'../../domain-page-failover-single-cluster/domain-page-failover-single-cluster',
17+
() =>
18+
jest.fn((props: { fromCluster?: string; toCluster?: string }) => (
19+
<div data-testid="mock-single-cluster-failover">
20+
{`${props.fromCluster} -> ${props.toCluster}`}
21+
</div>
22+
))
23+
);
24+
25+
describe(DomainPageFailoverActiveActive.name, () => {
26+
beforeEach(() => {
27+
jest.clearAllMocks();
28+
});
29+
30+
it('renders cluster failover when matching primary cluster failover is found', () => {
31+
const failoverEvent: FailoverEvent = {
32+
id: 'failover-1',
33+
createdTime: {
34+
seconds: '1700000000',
35+
nanos: 0,
36+
},
37+
failoverType: 'FAILOVER_TYPE_GRACEFUL',
38+
clusterFailovers: [
39+
{
40+
fromCluster: {
41+
activeClusterName: 'cluster-1',
42+
failoverVersion: '1',
43+
},
44+
toCluster: {
45+
activeClusterName: 'cluster-2',
46+
failoverVersion: '2',
47+
},
48+
clusterAttribute: null,
49+
},
50+
],
51+
};
52+
53+
setup({
54+
failoverEvent,
55+
clusterAttributeScope: PRIMARY_CLUSTER_SCOPE,
56+
});
57+
58+
expect(screen.getByText('Primary:')).toBeInTheDocument();
59+
expect(
60+
screen.getByTestId('mock-single-cluster-failover')
61+
).toBeInTheDocument();
62+
expect(screen.getByText('cluster-1 -> cluster-2')).toBeInTheDocument();
63+
expect(screen.getByText('See more')).toBeInTheDocument();
64+
});
65+
66+
it('renders cluster failover when matching non-primary cluster failover is found', () => {
67+
const failoverEvent: FailoverEvent = {
68+
id: 'failover-1',
69+
createdTime: {
70+
seconds: '1700000000',
71+
nanos: 0,
72+
},
73+
failoverType: 'FAILOVER_TYPE_GRACEFUL',
74+
clusterFailovers: [
75+
{
76+
fromCluster: {
77+
activeClusterName: 'cluster-1',
78+
failoverVersion: '1',
79+
},
80+
toCluster: {
81+
activeClusterName: 'cluster-2',
82+
failoverVersion: '2',
83+
},
84+
clusterAttribute: {
85+
scope: 'city',
86+
name: 'new_york',
87+
},
88+
},
89+
],
90+
};
91+
92+
setup({
93+
failoverEvent,
94+
clusterAttributeScope: 'city',
95+
clusterAttributeValue: 'new_york',
96+
});
97+
98+
expect(screen.getByText('city (new_york):')).toBeInTheDocument();
99+
expect(
100+
screen.getByTestId('mock-single-cluster-failover')
101+
).toBeInTheDocument();
102+
expect(screen.getByText('cluster-1 -> cluster-2')).toBeInTheDocument();
103+
expect(screen.getByText('See more')).toBeInTheDocument();
104+
});
105+
106+
it('does not render cluster failover section when clusterAttributeScope is set but clusterAttributeValue is undefined for non-primary scope', () => {
107+
const failoverEvent: FailoverEvent = {
108+
id: 'failover-1',
109+
createdTime: {
110+
seconds: '1700000000',
111+
nanos: 0,
112+
},
113+
failoverType: 'FAILOVER_TYPE_GRACEFUL',
114+
clusterFailovers: [
115+
{
116+
fromCluster: {
117+
activeClusterName: 'cluster-1',
118+
failoverVersion: '1',
119+
},
120+
toCluster: {
121+
activeClusterName: 'cluster-2',
122+
failoverVersion: '2',
123+
},
124+
clusterAttribute: {
125+
scope: 'region',
126+
name: 'us-east',
127+
},
128+
},
129+
],
130+
};
131+
132+
setup({
133+
failoverEvent,
134+
clusterAttributeScope: 'region',
135+
});
136+
137+
expect(
138+
screen.queryByTestId('mock-single-cluster-failover')
139+
).not.toBeInTheDocument();
140+
expect(screen.getByText('See more')).toBeInTheDocument();
141+
});
142+
143+
it('does not render cluster failover section when no matching cluster failover is found', () => {
144+
const failoverEvent: FailoverEvent = {
145+
id: 'failover-1',
146+
createdTime: {
147+
seconds: '1700000000',
148+
nanos: 0,
149+
},
150+
failoverType: 'FAILOVER_TYPE_GRACEFUL',
151+
clusterFailovers: [
152+
{
153+
fromCluster: {
154+
activeClusterName: 'cluster-1',
155+
failoverVersion: '1',
156+
},
157+
toCluster: {
158+
activeClusterName: 'cluster-2',
159+
failoverVersion: '2',
160+
},
161+
clusterAttribute: {
162+
scope: 'city',
163+
name: 'new_york',
164+
},
165+
},
166+
],
167+
};
168+
169+
setup({
170+
failoverEvent,
171+
clusterAttributeScope: 'city',
172+
clusterAttributeValue: 'los_angeles',
173+
});
174+
175+
expect(screen.queryByText('city (los_angeles):')).not.toBeInTheDocument();
176+
expect(
177+
screen.queryByTestId('mock-single-cluster-failover')
178+
).not.toBeInTheDocument();
179+
expect(screen.getByText('See more')).toBeInTheDocument();
180+
});
181+
182+
it('does not render cluster failover section when clusterAttributeScope is undefined', () => {
183+
const failoverEvent: FailoverEvent = {
184+
id: 'failover-1',
185+
createdTime: {
186+
seconds: '1700000000',
187+
nanos: 0,
188+
},
189+
failoverType: 'FAILOVER_TYPE_GRACEFUL',
190+
clusterFailovers: [
191+
{
192+
fromCluster: {
193+
activeClusterName: 'cluster-1',
194+
failoverVersion: '1',
195+
},
196+
toCluster: {
197+
activeClusterName: 'cluster-2',
198+
failoverVersion: '2',
199+
},
200+
clusterAttribute: null,
201+
},
202+
],
203+
};
204+
205+
setup({
206+
failoverEvent,
207+
clusterAttributeScope: undefined,
208+
});
209+
210+
expect(
211+
screen.queryByTestId('mock-single-cluster-failover')
212+
).not.toBeInTheDocument();
213+
expect(screen.getByText('See more')).toBeInTheDocument();
214+
});
215+
216+
it('renders "See more" button even when no matching cluster failover is found', () => {
217+
const failoverEvent: FailoverEvent = {
218+
id: 'failover-1',
219+
createdTime: {
220+
seconds: '1700000000',
221+
nanos: 0,
222+
},
223+
failoverType: 'FAILOVER_TYPE_GRACEFUL',
224+
clusterFailovers: [],
225+
};
226+
227+
setup({
228+
failoverEvent,
229+
clusterAttributeScope: PRIMARY_CLUSTER_SCOPE,
230+
});
231+
232+
expect(
233+
screen.queryByTestId('mock-single-cluster-failover')
234+
).not.toBeInTheDocument();
235+
expect(screen.getByText('See more')).toBeInTheDocument();
236+
});
237+
238+
it('selects the correct cluster failover when multiple cluster failovers exist', () => {
239+
const failoverEvent: FailoverEvent = {
240+
id: 'failover-1',
241+
createdTime: {
242+
seconds: '1700000000',
243+
nanos: 0,
244+
},
245+
failoverType: 'FAILOVER_TYPE_GRACEFUL',
246+
clusterFailovers: [
247+
{
248+
fromCluster: {
249+
activeClusterName: 'cluster-1',
250+
failoverVersion: '1',
251+
},
252+
toCluster: {
253+
activeClusterName: 'cluster-2',
254+
failoverVersion: '2',
255+
},
256+
clusterAttribute: {
257+
scope: 'city',
258+
name: 'new_york',
259+
},
260+
},
261+
{
262+
fromCluster: {
263+
activeClusterName: 'cluster-3',
264+
failoverVersion: '3',
265+
},
266+
toCluster: {
267+
activeClusterName: 'cluster-4',
268+
failoverVersion: '4',
269+
},
270+
clusterAttribute: {
271+
scope: 'region',
272+
name: 'us-east',
273+
},
274+
},
275+
],
276+
};
277+
278+
setup({
279+
failoverEvent,
280+
clusterAttributeScope: 'region',
281+
clusterAttributeValue: 'us-east',
282+
});
283+
284+
expect(screen.getByText('region (us-east):')).toBeInTheDocument();
285+
expect(
286+
screen.getByTestId('mock-single-cluster-failover')
287+
).toBeInTheDocument();
288+
expect(screen.getByText('cluster-3 -> cluster-4')).toBeInTheDocument();
289+
});
290+
});
291+
292+
function setup({
293+
failoverEvent,
294+
clusterAttributeScope,
295+
clusterAttributeValue,
296+
}: {
297+
failoverEvent: FailoverEvent;
298+
clusterAttributeScope?: string;
299+
clusterAttributeValue?: string;
300+
}) {
301+
jest.spyOn(usePageQueryParamsModule, 'default').mockReturnValue([
302+
{
303+
...mockDomainPageQueryParamsValues,
304+
clusterAttributeScope,
305+
clusterAttributeValue,
306+
} as typeof mockDomainPageQueryParamsValues,
307+
mockSetQueryParams,
308+
]);
309+
310+
render(<DomainPageFailoverActiveActive failoverEvent={failoverEvent} />);
311+
}

src/views/domain-page/domain-page-failover-active-active/domain-page-failover-active-active.styles.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import { styled as createStyled, type Theme } from 'baseui';
22

33
export const styled = {
4-
FailoverContainer: createStyled('div', ({ $theme }: { $theme: Theme }) => ({
5-
display: 'flex',
6-
gap: $theme.sizing.scale600,
7-
alignItems: 'baseline',
8-
})),
4+
FailoverEventContainer: createStyled(
5+
'div',
6+
({ $theme }: { $theme: Theme }) => ({
7+
display: 'flex',
8+
gap: $theme.sizing.scale600,
9+
alignItems: 'baseline',
10+
})
11+
),
912
ClusterFailoverContainer: createStyled(
1013
'div',
1114
({ $theme }: { $theme: Theme }) => ({

src/views/domain-page/domain-page-failover-active-active/domain-page-failover-active-active.tsx

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,29 @@ export default function DomainPageFailoverActiveActive({
2020
domainPageQueryParamsConfig
2121
);
2222

23-
const clusterFailoverForMaybeSelectedAttribute = useMemo(
24-
() =>
25-
failoverEvent.clusterFailovers.find((clusterFailover) =>
26-
clusterFailoverMatchesAttribute(
27-
clusterFailover,
28-
clusterAttributeScope,
29-
clusterAttributeValue
30-
)
31-
),
32-
[
33-
clusterAttributeScope,
34-
clusterAttributeValue,
35-
failoverEvent.clusterFailovers,
36-
]
37-
);
23+
const clusterFailoverForMaybeSelectedAttribute = useMemo(() => {
24+
if (
25+
!clusterAttributeScope ||
26+
(clusterAttributeScope !== PRIMARY_CLUSTER_SCOPE &&
27+
!clusterAttributeValue)
28+
)
29+
return undefined;
30+
31+
return failoverEvent.clusterFailovers.find((clusterFailover) =>
32+
clusterFailoverMatchesAttribute(
33+
clusterFailover,
34+
clusterAttributeScope,
35+
clusterAttributeValue
36+
)
37+
);
38+
}, [
39+
clusterAttributeScope,
40+
clusterAttributeValue,
41+
failoverEvent.clusterFailovers,
42+
]);
3843

3944
return (
40-
<styled.FailoverContainer>
45+
<styled.FailoverEventContainer>
4146
{clusterFailoverForMaybeSelectedAttribute && (
4247
<styled.ClusterFailoverContainer>
4348
<styled.ClusterAttributeLabel>
@@ -66,6 +71,6 @@ export default function DomainPageFailoverActiveActive({
6671
>
6772
See more
6873
</Button>
69-
</styled.FailoverContainer>
74+
</styled.FailoverEventContainer>
7075
);
7176
}

0 commit comments

Comments
 (0)