Changes:
- First draft of test coverage improvement for storybooks - code's page html rendering issue fixed
This commit is contained in:
parent
f1cb165bdd
commit
ddeade9775
@ -2,6 +2,7 @@ import { getKcClsx } from "keycloakify/login/lib/kcClsx";
|
||||
import type { PageProps } from "keycloakify/login/pages/PageProps";
|
||||
import type { KcContext } from "../KcContext";
|
||||
import type { I18n } from "../i18n";
|
||||
import { kcSanitize } from "keycloakify/lib/kcSanitize";
|
||||
|
||||
export default function Code(props: PageProps<Extract<KcContext, { pageId: "code.ftl" }>, I18n>) {
|
||||
const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
|
||||
@ -30,7 +31,14 @@ export default function Code(props: PageProps<Extract<KcContext, { pageId: "code
|
||||
<input id="code" className={kcClsx("kcTextareaClass")} defaultValue={code.code} />
|
||||
</>
|
||||
) : (
|
||||
<p id="error">{code.error}</p>
|
||||
code.error && (
|
||||
<p
|
||||
id="error"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: kcSanitize(code.error)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</Template>
|
||||
|
@ -16,3 +16,42 @@ type Story = StoryObj<typeof meta>;
|
||||
export const Default: Story = {
|
||||
render: () => <KcPageStory />
|
||||
};
|
||||
export const WithErrorCode: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
code: {
|
||||
success: false,
|
||||
error: "Failed to generate code"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithFrenchLanguage: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
locale: {
|
||||
currentLanguageTag: "fr"
|
||||
},
|
||||
code: {
|
||||
success: true,
|
||||
code: "XYZ789"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithHtmlErrorMessage: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
code: {
|
||||
success: false,
|
||||
error: "Something went wrong. <a href='https://example.com'>Try again</a>"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -16,3 +16,33 @@ type Story = StoryObj<typeof meta>;
|
||||
export const Default: Story = {
|
||||
render: () => <KcPageStory />
|
||||
};
|
||||
export const WithAIAFlow: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
triggered_from_aia: true,
|
||||
url: { loginAction: "/login-action" }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithoutAIAFlow: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
triggered_from_aia: false,
|
||||
url: { loginAction: "/login-action" }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithCustomButtonStyle: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
triggered_from_aia: true,
|
||||
url: { loginAction: "/login-action" }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -16,3 +16,13 @@ type Story = StoryObj<typeof meta>;
|
||||
export const Default: Story = {
|
||||
render: () => <KcPageStory />
|
||||
};
|
||||
export const WithCustomCredentialLabel: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
credentialLabel: "Test Credential",
|
||||
url: { loginAction: "/login-action" }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -26,3 +26,38 @@ export const WithAnotherMessage: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export const WithHtmlErrorMessage: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
message: {
|
||||
summary: "<strong>Error:</strong> Something went wrong. <a href='https://example.com'>Go back</a>"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const FrenchError: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
locale: { currentLanguageTag: "fr" },
|
||||
message: { summary: "Une erreur s'est produite" }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithSkipLink: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
message: { summary: "An error occurred" },
|
||||
skipLink: true,
|
||||
client: {
|
||||
baseUrl: "https://example.com"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -16,3 +16,14 @@ type Story = StoryObj<typeof meta>;
|
||||
export const Default: Story = {
|
||||
render: () => <KcPageStory />
|
||||
};
|
||||
export const WithoutRedirectUrl: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
logout: {
|
||||
clients: []
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -16,3 +16,47 @@ type Story = StoryObj<typeof meta>;
|
||||
export const Default: Story = {
|
||||
render: () => <KcPageStory />
|
||||
};
|
||||
export const WithFormValidationErrors: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
messagesPerField: {
|
||||
existsError: (fieldName: string) => ["email", "firstName"].includes(fieldName),
|
||||
get: (fieldName: string) => {
|
||||
if (fieldName === "email") return "Invalid email format.";
|
||||
if (fieldName === "firstName") return "First name is required.";
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithReadOnlyFields: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
profile: {
|
||||
attributesByName: {
|
||||
email: { value: "jane.doe@example.com", readOnly: true },
|
||||
firstName: { value: "Jane", readOnly: false }
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithPrefilledFormFields: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
profile: {
|
||||
attributesByName: {
|
||||
firstName: { value: "Jane" },
|
||||
lastName: { value: "Doe" },
|
||||
email: { value: "jane.doe@example.com" }
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -55,3 +55,42 @@ export const WithRequiredActions: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithPageRedirect: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
message: { summary: "You will be redirected shortly." },
|
||||
pageRedirectUri: "https://example.com"
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithoutClientBaseUrl: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
message: { summary: "No client base URL defined." },
|
||||
client: { baseUrl: undefined }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithMessageHeader: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
messageHeader: "Important Notice",
|
||||
message: { summary: "This is an important message." }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithAdvancedMessage: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
message: { summary: "Please take note of this <strong>important</strong> information." }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -231,3 +231,131 @@ export const WithErrorMessage: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export const WithOneSocialProvider: Story = {
|
||||
render: args => (
|
||||
<KcPageStory
|
||||
{...args}
|
||||
kcContext={{
|
||||
social: {
|
||||
displayInfo: true,
|
||||
providers: [
|
||||
{
|
||||
loginUrl: "google",
|
||||
alias: "google",
|
||||
providerId: "google",
|
||||
displayName: "Google",
|
||||
iconClasses: "fa fa-google"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export const WithTwoSocialProviders: Story = {
|
||||
render: args => (
|
||||
<KcPageStory
|
||||
{...args}
|
||||
kcContext={{
|
||||
social: {
|
||||
displayInfo: true,
|
||||
providers: [
|
||||
{
|
||||
loginUrl: "google",
|
||||
alias: "google",
|
||||
providerId: "google",
|
||||
displayName: "Google",
|
||||
iconClasses: "fa fa-google"
|
||||
},
|
||||
{
|
||||
loginUrl: "microsoft",
|
||||
alias: "microsoft",
|
||||
providerId: "microsoft",
|
||||
displayName: "Microsoft",
|
||||
iconClasses: "fa fa-windows"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithNoSocialProviders: Story = {
|
||||
render: args => (
|
||||
<KcPageStory
|
||||
{...args}
|
||||
kcContext={{
|
||||
social: {
|
||||
displayInfo: true,
|
||||
providers: []
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithMoreThanTwoSocialProviders: Story = {
|
||||
render: args => (
|
||||
<KcPageStory
|
||||
{...args}
|
||||
kcContext={{
|
||||
social: {
|
||||
displayInfo: true,
|
||||
providers: [
|
||||
{
|
||||
loginUrl: "google",
|
||||
alias: "google",
|
||||
providerId: "google",
|
||||
displayName: "Google",
|
||||
iconClasses: "fa fa-google"
|
||||
},
|
||||
{
|
||||
loginUrl: "microsoft",
|
||||
alias: "microsoft",
|
||||
providerId: "microsoft",
|
||||
displayName: "Microsoft",
|
||||
iconClasses: "fa fa-windows"
|
||||
},
|
||||
{
|
||||
loginUrl: "facebook",
|
||||
alias: "facebook",
|
||||
providerId: "facebook",
|
||||
displayName: "Facebook",
|
||||
iconClasses: "fa fa-facebook"
|
||||
},
|
||||
{
|
||||
loginUrl: "twitter",
|
||||
alias: "twitter",
|
||||
providerId: "twitter",
|
||||
displayName: "Twitter",
|
||||
iconClasses: "fa fa-twitter"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithSocialProvidersAndWithoutRememberMe: Story = {
|
||||
render: args => (
|
||||
<KcPageStory
|
||||
{...args}
|
||||
kcContext={{
|
||||
social: {
|
||||
displayInfo: true,
|
||||
providers: [
|
||||
{
|
||||
loginUrl: "google",
|
||||
alias: "google",
|
||||
providerId: "google",
|
||||
displayName: "Google",
|
||||
iconClasses: "fa fa-google"
|
||||
}
|
||||
]
|
||||
},
|
||||
realm: { rememberMe: false }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -41,3 +41,24 @@ export const WithError: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithAppInitiatedAction: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
isAppInitiatedAction: true
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export const WithPreFilledUserLabel: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
totp: {
|
||||
otpCredentials: [{ userLabel: "MyDevice" }]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -16,3 +16,49 @@ type Story = StoryObj<typeof meta>;
|
||||
export const Default: Story = {
|
||||
render: () => <KcPageStory />
|
||||
};
|
||||
export const WithIdpAlias: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
idpAlias: "Google",
|
||||
brokerContext: {
|
||||
username: "john.doe"
|
||||
},
|
||||
realm: {
|
||||
displayName: "MyRealm"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithoutIdpAlias: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
idpAlias: undefined,
|
||||
brokerContext: {
|
||||
username: "john.doe"
|
||||
},
|
||||
realm: {
|
||||
displayName: "MyRealm"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export const WithCustomRealmDisplayName: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
idpAlias: "Facebook",
|
||||
brokerContext: {
|
||||
username: "jane.doe"
|
||||
},
|
||||
realm: {
|
||||
displayName: "CustomRealm"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -215,3 +215,65 @@ export const WithTermsAcceptance: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithTermsNotAccepted: Story = {
|
||||
render: args => (
|
||||
<KcPageStory
|
||||
{...args}
|
||||
kcContext={{
|
||||
termsAcceptanceRequired: true,
|
||||
messagesPerField: {
|
||||
existsError: (fieldName: string) => fieldName === "termsAccepted",
|
||||
get: (fieldName: string) => (fieldName === "termsAccepted" ? "You must accept the terms." : undefined)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithFieldErrors: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
profile: {
|
||||
attributesByName: {
|
||||
username: { value: "" },
|
||||
email: { value: "invalid-email" }
|
||||
}
|
||||
},
|
||||
messagesPerField: {
|
||||
existsError: fieldName => ["username", "email"].includes(fieldName),
|
||||
get: fieldName => {
|
||||
if (fieldName === "username") return "Username is required.";
|
||||
if (fieldName === "email") return "Invalid email format.";
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithReadOnlyFields: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
profile: {
|
||||
attributesByName: {
|
||||
username: { value: "johndoe", readOnly: true },
|
||||
email: { value: "jhon.doe@gmail.com", readOnly: false }
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithAutoGeneratedUsername: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
profile: {
|
||||
attributesByName: {
|
||||
username: { value: "autogenerated_username" }
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -45,3 +45,32 @@ export const French: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const WithErrorMessage: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
messagesPerField: {
|
||||
existsError: () => true,
|
||||
get: () => "An error occurred while processing your request."
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export const Spanish: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
locale: {
|
||||
currentLanguageTag: "es"
|
||||
},
|
||||
"x-keycloakify": {
|
||||
messages: {
|
||||
termsText: "<p>Mis términos en <strong>Español</strong></p>"
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user