Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 141 additions & 12 deletions frontend/src/components/authchooser/AuthChooser.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@
* limitations under the License.
*/

import { configureStore } from '@reduxjs/toolkit';
import { Meta, StoryFn } from '@storybook/react';
import { delay, http, HttpResponse } from 'msw';
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import appStore from '../../redux/stores/store';
import { TestContext } from '../../test';
import { PureAuthChooser, PureAuthChooserProps } from './index';
import AuthChooser, { PureAuthChooser, PureAuthChooserProps } from './index';

export default {
title: 'AuthChooser',
Expand Down Expand Up @@ -50,13 +55,22 @@ const argFixture = {
clusterAuthType: '',
};

export const BasicAuthChooser = Template.bind({});
BasicAuthChooser.args = {
export const AuthMethodSelection = Template.bind({});
AuthMethodSelection.args = {
...argFixture,
clusterAuthType: 'oidc',
title: 'Select an authentication method',
};

export const TokenOnlyAuthMethod = Template.bind({});
TokenOnlyAuthMethod.args = {
...argFixture,
clusterAuthType: '',
title: 'Sign in with token',
};

export const Testing = Template.bind({});
Testing.args = {
export const LoadingStateDuringAuthFlow = Template.bind({});
LoadingStateDuringAuthFlow.args = {
...argFixture,
testingAuth: true,
};
Expand All @@ -67,15 +81,130 @@ HaveClusters.args = {
title: 'Select a cluster to sign in',
};

export const AuthTypeoidc = Template.bind({});
AuthTypeoidc.args = {
export const AuthenticationFailureError = Template.bind({});
AuthenticationFailureError.args = {
...argFixture,
clusterAuthType: 'oidc',
title: 'Sign in with OpenID Connect',
error: Error('Oh no! Some error happened?!?'),
};

export const AnError = Template.bind({});
AnError.args = {
export const AuthenticationFailureBadGateway = Template.bind({});
AuthenticationFailureBadGateway.args = {
...argFixture,
error: Error('Oh no! Some error happened?!?'),
error: Error('Bad Gateway'),
};

interface AuthChooserContainerStoryArgs {
clusterName: string;
clusterAuthType: string;
useToken?: boolean;
page: string;
}

function makeAuthChooserStore({
clusterName,
clusterAuthType,
useToken,
}: Omit<AuthChooserContainerStoryArgs, 'page'>) {
const baseState = appStore.getState();
const cluster = {
...(baseState.config?.clusters?.[clusterName] || {}),
name: clusterName,
auth_type: clusterAuthType,
useToken,
};
const preloadedState = {
...baseState,
config: {
...baseState.config,
clusters: {
[clusterName]: cluster,
},
allClusters: {
[clusterName]: cluster,
},
},
};

return configureStore({
reducer: (state = preloadedState) => state,
preloadedState,
middleware: getDefaultMiddleware =>
getDefaultMiddleware({
serializableCheck: false,
}),
});
}

function CurrentPath() {
const location = useLocation();

return <div>Current route: {location.pathname}</div>;
}

function SyncBrowserPath({ path }: { path: string }) {
useEffect(() => {
const previousPath = `${window.location.pathname}${window.location.search}${window.location.hash}`;
window.history.replaceState({}, '', path);

return () => {
window.history.replaceState({}, '', previousPath);
};
}, [path]);

return null;
}

const AuthChooserContainerTemplate: StoryFn<AuthChooserContainerStoryArgs> = args => {
const { clusterName, clusterAuthType, useToken, page } = args;
const path = `/c/${clusterName}/${page}`;

return (
<TestContext
store={makeAuthChooserStore({ clusterName, clusterAuthType, useToken })}
urlPrefix="/c"
routerMap={{ cluster: clusterName, ':page?': page }}
>
<SyncBrowserPath path={path} />
<AuthChooser />
<CurrentPath />
</TestContext>
);
};

export const ContainerAuthenticationFailureError = AuthChooserContainerTemplate.bind({});
ContainerAuthenticationFailureError.args = {
clusterName: 'some-cluster',
clusterAuthType: '',
page: 'login',
};
ContainerAuthenticationFailureError.parameters = {
msw: {
handlers: [
http.post(
'http://localhost:4466/clusters/:cluster/apis/authorization.k8s.io/v1/selfsubjectrulesreviews',
() =>
HttpResponse.json({ message: 'Bad Gateway' }, { status: 502, statusText: 'Bad Gateway' })
),
],
},
};

export const ContainerRedirectAfterSuccess = AuthChooserContainerTemplate.bind({});
ContainerRedirectAfterSuccess.args = {
clusterName: 'some-cluster',
clusterAuthType: '',
page: 'login',
};
ContainerRedirectAfterSuccess.parameters = {
msw: {
handlers: [
http.post(
'http://localhost:4466/clusters/:cluster/apis/authorization.k8s.io/v1/selfsubjectrulesreviews',
async () => {
await delay(200);
return HttpResponse.json({});
}
),
],
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
style="font-size: 1.25rem; font-weight: 500; line-height: 1.6;"
tabindex="-1"
>
Sign in with OpenID Connect
Select an authentication method
</h1>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<body>
<div
aria-hidden="true"
/>
<div
class="MuiDialog-root MuiModal-root css-1ixaqad-MuiModal-root-MuiDialog-root"
role="presentation"
>
<div
aria-hidden="true"
class="MuiBackdrop-root MuiModal-backdrop css-yiavyu-MuiBackdrop-root-MuiDialog-backdrop"
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;"
/>
<div
data-testid="sentinelStart"
tabindex="0"
/>
<div
class="MuiDialog-container MuiDialog-scrollPaper css-hz1bth-MuiDialog-container"
role="presentation"
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;"
tabindex="-1"
>
<div
aria-labelledby="authchooser-dialog-title"
class="MuiPaper-root MuiPaper-outlined MuiPaper-rounded MuiDialog-paper MuiDialog-paperScrollPaper MuiDialog-paperWidthSm css-1708vl9-MuiPaper-root-MuiDialog-paper"
role="dialog"
>
<h2
class="MuiTypography-root MuiTypography-h6 MuiDialogTitle-root css-wlr4ab-MuiTypography-root-MuiDialogTitle-root"
id="authchooser-dialog-title"
style="display: flex;"
>
<div
class="MuiGrid-root MuiGrid-container css-9cyib4-MuiGrid-root"
>
<div
class="MuiGrid-root MuiGrid-item css-13i4rnv-MuiGrid-root"
>
<h1
class="MuiTypography-root MuiTypography-h1 css-1kazmbo-MuiTypography-root"
style="font-size: 1.25rem; font-weight: 500; line-height: 1.6;"
>
<div
class="MuiBox-root css-19midj6"
/>
</h1>
</div>
<div
class="MuiGrid-root MuiGrid-item css-13i4rnv-MuiGrid-root"
>
<div
class="MuiBox-root css-0"
>
<button
aria-label="Show build information"
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-sizeSmall css-hvz71z-MuiButtonBase-root-MuiIconButton-root"
tabindex="0"
type="button"
>
<span
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
/>
</button>
</div>
</div>
</div>
</h2>
<div
class="MuiDialogContent-root MuiDialogContent-dividers css-gl9hfx-MuiDialogContent-root"
>
<main
class="MuiBox-root css-dvxtzn"
>
<h2
class="MuiTypography-root MuiTypography-h6 MuiDialogTitle-root css-8yphvn-MuiTypography-root-MuiDialogTitle-root"
id="authchooser-dialog-title"
style="display: flex;"
>
<div
class="MuiGrid-root MuiGrid-container css-9cyib4-MuiGrid-root"
>
<div
class="MuiGrid-root MuiGrid-item css-13i4rnv-MuiGrid-root"
>
<h1
class="MuiTypography-root MuiTypography-h1 css-1kazmbo-MuiTypography-root"
id="authchooser-dialog-title"
style="font-size: 1.25rem; font-weight: 500; line-height: 1.6;"
tabindex="-1"
>
some title
</h1>
</div>
</div>
</h2>
<div
class="MuiBox-root css-164mdc"
>
<div
class="MuiBox-root css-1c5ij41"
>
<div
class="MuiBox-root css-19midj6"
>
<p
class="MuiTypography-root MuiTypography-body1 MuiTypography-alignCenter css-18lkse1-MuiTypography-root"
>
Failed to connect. Please make sure the Kubernetes cluster is running and accessible. Error: Bad Gateway
</p>
</div>
<a
class="MuiTypography-root MuiTypography-inherit MuiLink-root MuiLink-underlineHover css-2ugbm1-MuiTypography-root-MuiLink-root"
href="/settings/cluster"
>
Cluster settings
</a>
</div>
<button
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"
tabindex="0"
type="button"
>
Try Again
<span
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
/>
</button>
</div>
</main>
<div
class="MuiBox-root css-dvxtzn"
>
<div
class="MuiBox-root css-oo0cqs"
role="button"
style="cursor: pointer;"
>
<div
class="MuiBox-root css-37urdo"
/>
<div
class="MuiBox-root css-1kuy7z7"
style="text-transform: uppercase;"
>
Back
</div>
</div>
</div>
</div>
</div>
</div>
<div
data-testid="sentinelEnd"
tabindex="0"
/>
</div>
</body>
Loading
Loading