Skip to content

Commit 73e6d43

Browse files
frontend: authchooser: expand auth flow stories
1 parent 594ca06 commit 73e6d43

8 files changed

+467
-14
lines changed

frontend/src/components/authchooser/AuthChooser.stories.tsx

Lines changed: 141 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,14 @@
1414
* limitations under the License.
1515
*/
1616

17+
import { configureStore } from '@reduxjs/toolkit';
1718
import { Meta, StoryFn } from '@storybook/react';
19+
import { delay, http, HttpResponse } from 'msw';
20+
import { useEffect } from 'react';
21+
import { useLocation } from 'react-router-dom';
22+
import appStore from '../../redux/stores/store';
1823
import { TestContext } from '../../test';
19-
import { PureAuthChooser, PureAuthChooserProps } from './index';
24+
import AuthChooser, { PureAuthChooser, PureAuthChooserProps } from './index';
2025

2126
export default {
2227
title: 'AuthChooser',
@@ -50,13 +55,22 @@ const argFixture = {
5055
clusterAuthType: '',
5156
};
5257

53-
export const BasicAuthChooser = Template.bind({});
54-
BasicAuthChooser.args = {
58+
export const AuthMethodSelection = Template.bind({});
59+
AuthMethodSelection.args = {
5560
...argFixture,
61+
clusterAuthType: 'oidc',
62+
title: 'Select an authentication method',
63+
};
64+
65+
export const TokenOnlyAuthMethod = Template.bind({});
66+
TokenOnlyAuthMethod.args = {
67+
...argFixture,
68+
clusterAuthType: '',
69+
title: 'Sign in with token',
5670
};
5771

58-
export const Testing = Template.bind({});
59-
Testing.args = {
72+
export const LoadingStateDuringAuthFlow = Template.bind({});
73+
LoadingStateDuringAuthFlow.args = {
6074
...argFixture,
6175
testingAuth: true,
6276
};
@@ -67,15 +81,130 @@ HaveClusters.args = {
6781
title: 'Select a cluster to sign in',
6882
};
6983

70-
export const AuthTypeoidc = Template.bind({});
71-
AuthTypeoidc.args = {
84+
export const AuthenticationFailureError = Template.bind({});
85+
AuthenticationFailureError.args = {
7286
...argFixture,
73-
clusterAuthType: 'oidc',
74-
title: 'Sign in with OpenID Connect',
87+
error: Error('Oh no! Some error happened?!?'),
7588
};
7689

77-
export const AnError = Template.bind({});
78-
AnError.args = {
90+
export const AuthenticationFailureBadGateway = Template.bind({});
91+
AuthenticationFailureBadGateway.args = {
7992
...argFixture,
80-
error: Error('Oh no! Some error happened?!?'),
93+
error: Error('Bad Gateway'),
94+
};
95+
96+
interface AuthChooserContainerStoryArgs {
97+
clusterName: string;
98+
clusterAuthType: string;
99+
useToken?: boolean;
100+
page: string;
101+
}
102+
103+
function makeAuthChooserStore({
104+
clusterName,
105+
clusterAuthType,
106+
useToken,
107+
}: Omit<AuthChooserContainerStoryArgs, 'page'>) {
108+
const baseState = appStore.getState();
109+
const cluster = {
110+
...(baseState.config?.clusters?.[clusterName] || {}),
111+
name: clusterName,
112+
auth_type: clusterAuthType,
113+
useToken,
114+
};
115+
const preloadedState = {
116+
...baseState,
117+
config: {
118+
...baseState.config,
119+
clusters: {
120+
[clusterName]: cluster,
121+
},
122+
allClusters: {
123+
[clusterName]: cluster,
124+
},
125+
},
126+
};
127+
128+
return configureStore({
129+
reducer: (state = preloadedState) => state,
130+
preloadedState,
131+
middleware: getDefaultMiddleware =>
132+
getDefaultMiddleware({
133+
serializableCheck: false,
134+
}),
135+
});
136+
}
137+
138+
function CurrentPath() {
139+
const location = useLocation();
140+
141+
return <div>Current route: {location.pathname}</div>;
142+
}
143+
144+
function SyncBrowserPath({ path }: { path: string }) {
145+
useEffect(() => {
146+
const previousPath = `${window.location.pathname}${window.location.search}${window.location.hash}`;
147+
window.history.replaceState({}, '', path);
148+
149+
return () => {
150+
window.history.replaceState({}, '', previousPath);
151+
};
152+
}, [path]);
153+
154+
return null;
155+
}
156+
157+
const AuthChooserContainerTemplate: StoryFn<AuthChooserContainerStoryArgs> = args => {
158+
const { clusterName, clusterAuthType, useToken, page } = args;
159+
const path = `/c/${clusterName}/${page}`;
160+
161+
return (
162+
<TestContext
163+
store={makeAuthChooserStore({ clusterName, clusterAuthType, useToken })}
164+
urlPrefix="/c"
165+
routerMap={{ cluster: clusterName, ':page?': page }}
166+
>
167+
<SyncBrowserPath path={path} />
168+
<AuthChooser />
169+
<CurrentPath />
170+
</TestContext>
171+
);
172+
};
173+
174+
export const ContainerAuthenticationFailureError = AuthChooserContainerTemplate.bind({});
175+
ContainerAuthenticationFailureError.args = {
176+
clusterName: 'some-cluster',
177+
clusterAuthType: '',
178+
page: 'login',
179+
};
180+
ContainerAuthenticationFailureError.parameters = {
181+
msw: {
182+
handlers: [
183+
http.post(
184+
'http://localhost:4466/clusters/:cluster/apis/authorization.k8s.io/v1/selfsubjectrulesreviews',
185+
() =>
186+
HttpResponse.json({ message: 'Bad Gateway' }, { status: 502, statusText: 'Bad Gateway' })
187+
),
188+
],
189+
},
190+
};
191+
192+
export const ContainerRedirectAfterSuccess = AuthChooserContainerTemplate.bind({});
193+
ContainerRedirectAfterSuccess.args = {
194+
clusterName: 'some-cluster',
195+
clusterAuthType: '',
196+
page: 'login',
197+
};
198+
ContainerRedirectAfterSuccess.parameters = {
199+
msw: {
200+
handlers: [
201+
http.post(
202+
'http://localhost:4466/clusters/:cluster/apis/authorization.k8s.io/v1/selfsubjectrulesreviews',
203+
async () => {
204+
await delay(200);
205+
return HttpResponse.json({});
206+
}
207+
),
208+
],
209+
},
81210
};

frontend/src/components/authchooser/__snapshots__/AuthChooser.AuthTypeoidc.stories.storyshot renamed to frontend/src/components/authchooser/__snapshots__/AuthChooser.AuthMethodSelection.stories.storyshot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
style="font-size: 1.25rem; font-weight: 500; line-height: 1.6;"
9090
tabindex="-1"
9191
>
92-
Sign in with OpenID Connect
92+
Select an authentication method
9393
</h1>
9494
</div>
9595
</div>
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
<body>
2+
<div
3+
aria-hidden="true"
4+
/>
5+
<div
6+
class="MuiDialog-root MuiModal-root css-1ixaqad-MuiModal-root-MuiDialog-root"
7+
role="presentation"
8+
>
9+
<div
10+
aria-hidden="true"
11+
class="MuiBackdrop-root MuiModal-backdrop css-yiavyu-MuiBackdrop-root-MuiDialog-backdrop"
12+
style="opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
13+
/>
14+
<div
15+
data-testid="sentinelStart"
16+
tabindex="0"
17+
/>
18+
<div
19+
class="MuiDialog-container MuiDialog-scrollPaper css-hz1bth-MuiDialog-container"
20+
role="presentation"
21+
style="opacity: 1; webkit-transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
22+
tabindex="-1"
23+
>
24+
<div
25+
aria-labelledby="authchooser-dialog-title"
26+
class="MuiPaper-root MuiPaper-outlined MuiPaper-rounded MuiDialog-paper MuiDialog-paperScrollPaper MuiDialog-paperWidthSm css-1708vl9-MuiPaper-root-MuiDialog-paper"
27+
role="dialog"
28+
>
29+
<h2
30+
class="MuiTypography-root MuiTypography-h6 MuiDialogTitle-root css-wlr4ab-MuiTypography-root-MuiDialogTitle-root"
31+
id="authchooser-dialog-title"
32+
style="display: flex;"
33+
>
34+
<div
35+
class="MuiGrid-root MuiGrid-container css-9cyib4-MuiGrid-root"
36+
>
37+
<div
38+
class="MuiGrid-root MuiGrid-item css-13i4rnv-MuiGrid-root"
39+
>
40+
<h1
41+
class="MuiTypography-root MuiTypography-h1 css-1kazmbo-MuiTypography-root"
42+
style="font-size: 1.25rem; font-weight: 500; line-height: 1.6;"
43+
>
44+
<div
45+
class="MuiBox-root css-19midj6"
46+
/>
47+
</h1>
48+
</div>
49+
<div
50+
class="MuiGrid-root MuiGrid-item css-13i4rnv-MuiGrid-root"
51+
>
52+
<div
53+
class="MuiBox-root css-0"
54+
>
55+
<button
56+
aria-label="Show build information"
57+
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-sizeSmall css-hvz71z-MuiButtonBase-root-MuiIconButton-root"
58+
tabindex="0"
59+
type="button"
60+
>
61+
<span
62+
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
63+
/>
64+
</button>
65+
</div>
66+
</div>
67+
</div>
68+
</h2>
69+
<div
70+
class="MuiDialogContent-root MuiDialogContent-dividers css-gl9hfx-MuiDialogContent-root"
71+
>
72+
<main
73+
class="MuiBox-root css-dvxtzn"
74+
>
75+
<h2
76+
class="MuiTypography-root MuiTypography-h6 MuiDialogTitle-root css-8yphvn-MuiTypography-root-MuiDialogTitle-root"
77+
id="authchooser-dialog-title"
78+
style="display: flex;"
79+
>
80+
<div
81+
class="MuiGrid-root MuiGrid-container css-9cyib4-MuiGrid-root"
82+
>
83+
<div
84+
class="MuiGrid-root MuiGrid-item css-13i4rnv-MuiGrid-root"
85+
>
86+
<h1
87+
class="MuiTypography-root MuiTypography-h1 css-1kazmbo-MuiTypography-root"
88+
id="authchooser-dialog-title"
89+
style="font-size: 1.25rem; font-weight: 500; line-height: 1.6;"
90+
tabindex="-1"
91+
>
92+
some title
93+
</h1>
94+
</div>
95+
</div>
96+
</h2>
97+
<div
98+
class="MuiBox-root css-164mdc"
99+
>
100+
<div
101+
class="MuiBox-root css-1c5ij41"
102+
>
103+
<div
104+
class="MuiBox-root css-19midj6"
105+
>
106+
<p
107+
class="MuiTypography-root MuiTypography-body1 MuiTypography-alignCenter css-18lkse1-MuiTypography-root"
108+
>
109+
Failed to connect. Please make sure the Kubernetes cluster is running and accessible. Error: Bad Gateway
110+
</p>
111+
</div>
112+
<a
113+
class="MuiTypography-root MuiTypography-inherit MuiLink-root MuiLink-underlineHover css-2ugbm1-MuiTypography-root-MuiLink-root"
114+
href="/settings/cluster"
115+
>
116+
Cluster settings
117+
</a>
118+
</div>
119+
<button
120+
class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorPrimary MuiButton-disableElevation MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorPrimary MuiButton-disableElevation css-gn8fa3-MuiButtonBase-root-MuiButton-root"
121+
tabindex="0"
122+
type="button"
123+
>
124+
Try Again
125+
<span
126+
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
127+
/>
128+
</button>
129+
</div>
130+
</main>
131+
<div
132+
class="MuiBox-root css-dvxtzn"
133+
>
134+
<div
135+
class="MuiBox-root css-oo0cqs"
136+
role="button"
137+
style="cursor: pointer;"
138+
>
139+
<div
140+
class="MuiBox-root css-37urdo"
141+
/>
142+
<div
143+
class="MuiBox-root css-1kuy7z7"
144+
style="text-transform: uppercase;"
145+
>
146+
Back
147+
</div>
148+
</div>
149+
</div>
150+
</div>
151+
</div>
152+
</div>
153+
<div
154+
data-testid="sentinelEnd"
155+
tabindex="0"
156+
/>
157+
</div>
158+
</body>

frontend/src/components/authchooser/__snapshots__/AuthChooser.AnError.stories.storyshot renamed to frontend/src/components/authchooser/__snapshots__/AuthChooser.AuthenticationFailureError.stories.storyshot

File renamed without changes.

0 commit comments

Comments
 (0)