Changes:
- First draft of test coverage improvement for storybooks - code's page html rendering issue fixed
This commit is contained in:
parent
94779c3476
commit
c9d7fc1b6e
@ -2,6 +2,7 @@ import { getKcClsx } from "keycloakify/login/lib/kcClsx";
|
|||||||
import type { PageProps } from "keycloakify/login/pages/PageProps";
|
import type { PageProps } from "keycloakify/login/pages/PageProps";
|
||||||
import type { KcContext } from "../KcContext";
|
import type { KcContext } from "../KcContext";
|
||||||
import type { I18n } from "../i18n";
|
import type { I18n } from "../i18n";
|
||||||
|
import { kcSanitize } from "keycloakify/lib/kcSanitize";
|
||||||
|
|
||||||
export default function Code(props: PageProps<Extract<KcContext, { pageId: "code.ftl" }>, I18n>) {
|
export default function Code(props: PageProps<Extract<KcContext, { pageId: "code.ftl" }>, I18n>) {
|
||||||
const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
|
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} />
|
<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>
|
</div>
|
||||||
</Template>
|
</Template>
|
||||||
|
@ -16,3 +16,42 @@ type Story = StoryObj<typeof meta>;
|
|||||||
export const Default: Story = {
|
export const Default: Story = {
|
||||||
render: () => <KcPageStory />
|
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 = {
|
export const Default: Story = {
|
||||||
render: () => <KcPageStory />
|
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 = {
|
export const Default: Story = {
|
||||||
render: () => <KcPageStory />
|
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 = {
|
export const Default: Story = {
|
||||||
render: () => <KcPageStory />
|
render: () => <KcPageStory />
|
||||||
};
|
};
|
||||||
|
export const WithoutRedirectUrl: Story = {
|
||||||
|
render: () => (
|
||||||
|
<KcPageStory
|
||||||
|
kcContext={{
|
||||||
|
logout: {
|
||||||
|
clients: []
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
@ -16,3 +16,47 @@ type Story = StoryObj<typeof meta>;
|
|||||||
export const Default: Story = {
|
export const Default: Story = {
|
||||||
render: () => <KcPageStory />
|
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 = {
|
export const Default: Story = {
|
||||||
render: () => <KcPageStory />
|
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"
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
@ -185,3 +185,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