Skip to content

Commit 1aa1d98

Browse files
committed
Hide tabs when stream query failed
1 parent c2719d3 commit 1aa1d98

3 files changed

Lines changed: 114 additions & 49 deletions

File tree

packages/manager/src/features/Delivery/Streams/Stream/StreamLanding.test.tsx

Lines changed: 79 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,22 @@ import {
77
streamFactory,
88
} from 'src/factories';
99
import { StreamLanding } from 'src/features/Delivery/Streams/Stream/StreamLanding';
10-
import { http, HttpResponse, server } from 'src/mocks/testServer';
1110
import { renderWithTheme } from 'src/utilities/testHelpers';
1211

1312
import type { Flags } from 'src/featureFlags';
1413

14+
const queryMocks = vi.hoisted(() => ({
15+
useStreamQuery: vi.fn().mockReturnValue({}),
16+
}));
17+
18+
vi.mock('@linode/queries', async () => {
19+
const actual = await vi.importActual('@linode/queries');
20+
return {
21+
...actual,
22+
useStreamQuery: queryMocks.useStreamQuery,
23+
};
24+
});
25+
1526
const streamId = 123;
1627
const mockDestinations = [
1728
akamaiObjectStorageDestinationFactory.build({ id: 1 }),
@@ -30,45 +41,83 @@ describe('StreamLanding', () => {
3041
});
3142
};
3243

33-
beforeEach(async () => {
34-
server.use(
35-
http.get(`*/monitor/streams/${streamId}`, () => {
36-
return HttpResponse.json(mockStream);
37-
})
38-
);
44+
describe('and stream has loaded successfully', () => {
45+
beforeEach(async () => {
46+
queryMocks.useStreamQuery.mockReturnValue({
47+
data: mockStream,
48+
isLoading: false,
49+
});
50+
});
51+
52+
describe('and metrics are not enabled', () => {
53+
const flags = {
54+
aclpLogs: {
55+
enabled: true,
56+
beta: false,
57+
metricsEnabled: false,
58+
},
59+
};
60+
61+
it('should render the summary and not the metrics tab', async () => {
62+
renderComponent(flags);
63+
64+
screen.getByText('Summary');
65+
expect(screen.queryByText('Metrics')).not.toBeInTheDocument();
66+
});
67+
});
68+
69+
describe('and metrics are enabled', () => {
70+
const flags = {
71+
aclpLogs: {
72+
enabled: true,
73+
beta: false,
74+
metricsEnabled: true,
75+
},
76+
};
77+
78+
it('should render the summary tab and metrics tab', async () => {
79+
renderComponent(flags);
80+
81+
screen.getByText('Summary');
82+
expect(screen.queryByText('Metrics')).toBeInTheDocument();
83+
});
84+
});
3985
});
4086

41-
describe('and metrics are not enabled', () => {
42-
const flags = {
43-
aclpLogs: {
44-
enabled: true,
45-
beta: false,
46-
metricsEnabled: false,
47-
},
48-
};
87+
describe('and stream is loading', () => {
88+
beforeEach(async () => {
89+
queryMocks.useStreamQuery.mockReturnValue({
90+
isLoading: true,
91+
});
92+
});
4993

50-
it('should render the summary and not the metrics tab', async () => {
51-
renderComponent(flags);
94+
it('should render loading spinner', async () => {
95+
renderComponent({});
5296

53-
screen.getByText('Summary');
97+
expect(screen.queryByText('Summary')).not.toBeInTheDocument();
5498
expect(screen.queryByText('Metrics')).not.toBeInTheDocument();
99+
100+
const loadingElement = screen.queryByTestId('circle-progress');
101+
expect(loadingElement).toBeInTheDocument();
55102
});
56103
});
57104

58-
describe('and metrics are enabled', () => {
59-
const flags = {
60-
aclpLogs: {
61-
enabled: true,
62-
beta: false,
63-
metricsEnabled: true,
64-
},
65-
};
105+
describe('and stream request threw error', () => {
106+
const streamErrorMessage = 'Stream not found';
107+
beforeEach(async () => {
108+
queryMocks.useStreamQuery.mockReturnValue({
109+
isLoading: false,
110+
error: [{ reason: streamErrorMessage }],
111+
});
112+
});
113+
114+
it('should render error state with message', async () => {
115+
renderComponent({});
66116

67-
it('should render the summary tab and metrics tab', async () => {
68-
renderComponent(flags);
117+
expect(screen.queryByText('Summary')).not.toBeInTheDocument();
118+
expect(screen.queryByText('Metrics')).not.toBeInTheDocument();
69119

70-
screen.getByText('Summary');
71-
expect(screen.queryByText('Metrics')).toBeInTheDocument();
120+
expect(screen.queryByText(streamErrorMessage)).toBeInTheDocument();
72121
});
73122
});
74123
});

packages/manager/src/features/Delivery/Streams/Stream/StreamLanding.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { useStreamQuery } from '@linode/queries';
2+
import { Box, CircleProgress, ErrorState } from '@linode/ui';
13
import { useParams } from '@tanstack/react-router';
24
import * as React from 'react';
35
import { useMemo } from 'react';
@@ -16,6 +18,7 @@ import { useIsACLPLogsEnabled } from 'src/features/Delivery/deliveryUtils';
1618
import { StreamMetrics } from 'src/features/Delivery/Streams/Stream/StreamMetrics';
1719
import { StreamEdit } from 'src/features/Delivery/Streams/StreamForm/StreamEdit';
1820
import { useTabs } from 'src/hooks/useTabs';
21+
import { getAPIErrorOrDefault } from 'src/utilities/errorUtils';
1922

2023
import type { Tab } from 'src/hooks/useTabs';
2124

@@ -45,6 +48,12 @@ export const StreamLanding = () => {
4548

4649
const { handleTabChange, tabIndex, tabs } = useTabs(activeTabs);
4750

51+
const { isLoading: isLoadingStream, error: errorStream } = useStreamQuery(
52+
Number(streamId)
53+
);
54+
const streamErrorDefaultMessage =
55+
'There was an error retrieving stream. Please reload and try again.';
56+
4857
const landingHeaderProps: LandingHeaderProps = {
4958
breadcrumbProps: {
5059
pathname: '/logs/delivery/streams/summary',
@@ -61,6 +70,24 @@ export const StreamLanding = () => {
6170
title: `Stream ${streamId}`,
6271
};
6372

73+
if (isLoadingStream) {
74+
return (
75+
<Box display="flex" justifyContent="center">
76+
<CircleProgress />
77+
</Box>
78+
);
79+
}
80+
81+
if (errorStream) {
82+
return (
83+
<ErrorState
84+
errorText={
85+
getAPIErrorOrDefault(errorStream, streamErrorDefaultMessage)[0].reason
86+
}
87+
/>
88+
);
89+
}
90+
6491
return (
6592
<>
6693
<DocumentTitleSegment segment="Stream" />

packages/manager/src/features/Delivery/Streams/StreamForm/StreamEdit.tsx

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@ export const StreamEdit = () => {
2121
isLoading: isLoadingDestinations,
2222
error: errorDestinations,
2323
} = useAllDestinationsQuery();
24-
const {
25-
data: stream,
26-
isLoading: isLoadingStream,
27-
error: errorStream,
28-
} = useStreamQuery(Number(streamId));
24+
const { data: stream, isLoading: isLoadingStream } = useStreamQuery(
25+
Number(streamId)
26+
);
2927

3028
const form = useForm<StreamAndDestinationFormType>({
3129
defaultValues: {
@@ -90,26 +88,17 @@ export const StreamEdit = () => {
9088
<CircleProgress size="md" />
9189
</Box>
9290
)}
93-
{errorStream && (
94-
<ErrorState
95-
compact
96-
errorText="There was an error retrieving stream. Please reload and try again."
97-
/>
98-
)}
9991
{errorDestinations && (
10092
<ErrorState
10193
compact
10294
errorText="There was an error retrieving destinations. Please reload and try again."
10395
/>
10496
)}
105-
{!isLoadingStream &&
106-
!isLoadingDestinations &&
107-
!errorStream &&
108-
!errorDestinations && (
109-
<FormProvider {...form}>
110-
<StreamForm mode="edit" streamId={streamId} />
111-
</FormProvider>
112-
)}
97+
{!isLoadingStream && !isLoadingDestinations && !errorDestinations && (
98+
<FormProvider {...form}>
99+
<StreamForm mode="edit" streamId={streamId} />
100+
</FormProvider>
101+
)}
113102
</>
114103
);
115104
};

0 commit comments

Comments
 (0)