account page test coverage improved
This commit is contained in:
parent
0cf8caa53b
commit
3ff01d186d
@ -16,3 +16,105 @@ type Story = StoryObj<typeof meta>;
|
||||
export const Default: Story = {
|
||||
render: () => <KcPageStory />
|
||||
};
|
||||
|
||||
/**
|
||||
* UsernameNotEditable:
|
||||
* - Purpose: Test the scenario where the username field is not editable.
|
||||
* - Scenario: The component renders, but the username field is disabled.
|
||||
* - Key Aspect: Ensures that the `editUsernameAllowed` condition is respected and the username field is read-only.
|
||||
*/
|
||||
export const UsernameNotEditable: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
account: {
|
||||
username: "john_doe",
|
||||
email: "john.doe@gmail.com",
|
||||
firstName: "John",
|
||||
lastName: "Doe"
|
||||
},
|
||||
realm: {
|
||||
registrationEmailAsUsername: false,
|
||||
editUsernameAllowed: false
|
||||
},
|
||||
referrer: {
|
||||
url: "/home"
|
||||
},
|
||||
url: {
|
||||
accountUrl: "/account"
|
||||
},
|
||||
messagesPerField: {
|
||||
printIfExists: () => ""
|
||||
},
|
||||
stateChecker: "state-checker"
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* WithValidationErrors:
|
||||
* - Purpose: Test the form when there are validation errors.
|
||||
* - Scenario: The component renders with error messages for invalid input in the fields.
|
||||
* - Key Aspect: Ensures that error messages are properly displayed and the user can correct their inputs.
|
||||
*/
|
||||
export const WithValidationErrors: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
account: {
|
||||
username: "john_doe",
|
||||
email: "",
|
||||
firstName: "",
|
||||
lastName: "Doe"
|
||||
},
|
||||
realm: {
|
||||
registrationEmailAsUsername: false,
|
||||
editUsernameAllowed: true
|
||||
},
|
||||
referrer: {
|
||||
url: "/home"
|
||||
},
|
||||
url: {
|
||||
accountUrl: "/account"
|
||||
},
|
||||
messagesPerField: {
|
||||
printIfExists: field => (field === "email" || field === "firstName" ? "has-error" : "")
|
||||
},
|
||||
stateChecker: "state-checker"
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
/**
|
||||
* EmailAsUsername:
|
||||
* - Purpose: Test the form where email is used as the username.
|
||||
* - Scenario: The component renders without a separate username field, and the email field is treated as the username.
|
||||
* - Key Aspect: Ensures the form functions correctly when `registrationEmailAsUsername` is enabled.
|
||||
*/
|
||||
export const EmailAsUsername: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
account: {
|
||||
email: "john.doe@gmail.com",
|
||||
firstName: "John",
|
||||
lastName: "Doe"
|
||||
},
|
||||
realm: {
|
||||
registrationEmailAsUsername: true
|
||||
},
|
||||
referrer: {
|
||||
url: "/home"
|
||||
},
|
||||
url: {
|
||||
accountUrl: "/account"
|
||||
},
|
||||
messagesPerField: {
|
||||
printIfExists: () => ""
|
||||
},
|
||||
stateChecker: "state-checker"
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -78,3 +78,151 @@ export const Default: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
// No Available Roles or Grants Scenario
|
||||
export const NoAvailableRolesOrGrants: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "applications.ftl",
|
||||
applications: {
|
||||
applications: [
|
||||
{
|
||||
realmRolesAvailable: [],
|
||||
resourceRolesAvailable: {},
|
||||
additionalGrants: [],
|
||||
clientScopesGranted: [],
|
||||
effectiveUrl: "#",
|
||||
client: {
|
||||
clientId: "application1",
|
||||
name: "Application 1",
|
||||
consentRequired: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
// Consent Not Required Scenario
|
||||
export const ConsentNotRequired: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "applications.ftl",
|
||||
applications: {
|
||||
applications: [
|
||||
{
|
||||
realmRolesAvailable: [],
|
||||
resourceRolesAvailable: {},
|
||||
additionalGrants: [],
|
||||
clientScopesGranted: [],
|
||||
effectiveUrl: "#",
|
||||
client: {
|
||||
clientId: "application1",
|
||||
name: "Application 1",
|
||||
consentRequired: false // No consent required
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
// No Roles Available but Consent Required Scenario
|
||||
export const NoRolesButConsentRequired: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "applications.ftl",
|
||||
applications: {
|
||||
applications: [
|
||||
{
|
||||
realmRolesAvailable: [],
|
||||
resourceRolesAvailable: {},
|
||||
additionalGrants: [],
|
||||
clientScopesGranted: ["scope1", "scope2"], // Consent required but no roles
|
||||
effectiveUrl: "#",
|
||||
client: {
|
||||
clientId: "application1",
|
||||
name: "Application 1",
|
||||
consentRequired: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
// Only Resource Roles Available Scenario
|
||||
export const OnlyResourceRolesAvailable: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "applications.ftl",
|
||||
applications: {
|
||||
applications: [
|
||||
{
|
||||
realmRolesAvailable: [], // No realm roles
|
||||
resourceRolesAvailable: {
|
||||
resource1: [
|
||||
{
|
||||
roleName: "Resource Role Name 1",
|
||||
roleDescription: "Resource role 1 description",
|
||||
clientName: "Client Name 1",
|
||||
clientId: "client1"
|
||||
}
|
||||
]
|
||||
},
|
||||
additionalGrants: [],
|
||||
clientScopesGranted: [],
|
||||
effectiveUrl: "#",
|
||||
client: {
|
||||
clientId: "application1",
|
||||
name: "Application 1",
|
||||
consentRequired: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
// No Additional Grants Scenario
|
||||
export const NoAdditionalGrants: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "applications.ftl",
|
||||
applications: {
|
||||
applications: [
|
||||
{
|
||||
realmRolesAvailable: [
|
||||
{
|
||||
name: "Realm Role Name 1"
|
||||
}
|
||||
],
|
||||
resourceRolesAvailable: {},
|
||||
additionalGrants: [], // No additional grants
|
||||
clientScopesGranted: [],
|
||||
effectiveUrl: "#",
|
||||
client: {
|
||||
clientId: "application1",
|
||||
name: "Application 1",
|
||||
consentRequired: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -36,3 +36,61 @@ export const NotConnected: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* RemoveLinkNotPossible:
|
||||
* - Federated identities are connected, but the user cannot remove them due to restrictions.
|
||||
*/
|
||||
export const RemoveLinkNotPossible: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "federatedIdentity.ftl",
|
||||
federatedIdentity: {
|
||||
identities: [
|
||||
{
|
||||
providerId: "google",
|
||||
displayName: "Google",
|
||||
userName: "john.doe@gmail.com",
|
||||
connected: true
|
||||
}
|
||||
],
|
||||
removeLinkPossible: false
|
||||
},
|
||||
stateChecker: "1234",
|
||||
url: {
|
||||
socialUrl: "/social"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* AddLinkForUnconnectedIdentity:
|
||||
* - The user has an identity that is not connected and can add it.
|
||||
*/
|
||||
export const AddLinkForUnconnectedIdentity: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "federatedIdentity.ftl",
|
||||
federatedIdentity: {
|
||||
identities: [
|
||||
{
|
||||
providerId: "github",
|
||||
displayName: "GitHub",
|
||||
userName: "",
|
||||
connected: false
|
||||
}
|
||||
],
|
||||
removeLinkPossible: true
|
||||
},
|
||||
stateChecker: "1234",
|
||||
url: {
|
||||
socialUrl: "/social"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -355,3 +355,107 @@ export const Default: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const LogsMissingDetails: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "log.ftl",
|
||||
log: {
|
||||
events: [
|
||||
{
|
||||
date: "2024-04-26T12:29:08Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "",
|
||||
details: [],
|
||||
event: "login"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const SingleLogEntry: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "log.ftl",
|
||||
log: {
|
||||
events: [
|
||||
{
|
||||
date: "2024-04-26T12:29:08Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{ key: "auth_method", value: "openid-connect" },
|
||||
{ key: "username", value: "john.doe" }
|
||||
],
|
||||
event: "login"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const LogsWithLongDetails: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "log.ftl",
|
||||
log: {
|
||||
events: [
|
||||
{
|
||||
date: "2024-04-26T12:29:08Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{ key: "auth_method", value: "openid-connect" },
|
||||
{ key: "username", value: "john.doe" },
|
||||
{ key: "session_duration", value: "2 hours 30 minutes 45 seconds" },
|
||||
{ key: "location", value: "Windsor, Ontario, Canada" },
|
||||
{ key: "user_agent", value: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" }
|
||||
],
|
||||
event: "login"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const EmptyClientField: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "log.ftl",
|
||||
log: {
|
||||
events: [
|
||||
{
|
||||
date: "2024-04-26T12:29:08Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "", // Empty client field
|
||||
details: [
|
||||
{ key: "auth_method", value: "openid-connect" },
|
||||
{ key: "username", value: "john.doe" }
|
||||
],
|
||||
event: "login"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
export const NoLogsAvailable: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
pageId: "log.ftl",
|
||||
log: {
|
||||
events: [] // No log events
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -26,3 +26,79 @@ export const WithMessage: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
/**
|
||||
* FirstTimePasswordSetup:
|
||||
* - Purpose: Tests the page when no password is set (e.g., first login).
|
||||
* - Scenario: This renders the form without the current password field.
|
||||
* - Key Aspect: Ensures the page only displays fields for setting a new password.
|
||||
*/
|
||||
export const FirstTimePasswordSetup: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
account: {
|
||||
username: "john_doe"
|
||||
},
|
||||
password: {
|
||||
passwordSet: false
|
||||
},
|
||||
url: {
|
||||
passwordUrl: "/password"
|
||||
},
|
||||
stateChecker: "state-checker"
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* IncorrectCurrentPassword:
|
||||
* - Purpose: Simulates validation error when the current password is incorrect.
|
||||
* - Scenario: This renders the page with an error message indicating the current password is incorrect.
|
||||
* - Key Aspect: Validates that an error message is correctly displayed for the current password input.
|
||||
*/
|
||||
export const IncorrectCurrentPassword: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
message: { type: "error", summary: "Incorrect current password." },
|
||||
account: {
|
||||
username: "john_doe"
|
||||
},
|
||||
password: {
|
||||
passwordSet: true
|
||||
},
|
||||
url: {
|
||||
passwordUrl: "/password"
|
||||
},
|
||||
stateChecker: "state-checker"
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* SubmissionSuccessWithRedirect:
|
||||
* - Purpose: Simulates a successful form submission with a redirect or success message.
|
||||
* - Scenario: After successfully changing the password, a success message and redirect behavior are triggered.
|
||||
* - Key Aspect: Verifies the handling of successful submissions.
|
||||
*/
|
||||
export const SubmissionSuccessWithRedirect: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
message: { type: "success", summary: "Password successfully changed." },
|
||||
account: {
|
||||
username: "john_doe"
|
||||
},
|
||||
password: {
|
||||
passwordSet: true
|
||||
},
|
||||
url: {
|
||||
passwordUrl: "/password"
|
||||
},
|
||||
stateChecker: "state-checker"
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -57,3 +57,97 @@ export const WithError: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
/**
|
||||
* No active sessions scenario:
|
||||
* - Simulates the scenario where no sessions are active for the user.
|
||||
*/
|
||||
export const NoActiveSessions: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
sessions: {
|
||||
sessions: []
|
||||
},
|
||||
stateChecker: "randomStateCheckerValue"
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* Single session scenario:
|
||||
* - Displays only one active session with session details.
|
||||
*/
|
||||
export const SingleSession: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
sessions: {
|
||||
sessions: [
|
||||
{
|
||||
expires: "2024-04-26T18:14:19Z",
|
||||
clients: ["account"],
|
||||
ipAddress: "172.20.0.1",
|
||||
started: "2024-04-26T08:14:19Z",
|
||||
lastAccess: "2024-04-26T08:30:54Z",
|
||||
id: "single-session-id"
|
||||
}
|
||||
]
|
||||
},
|
||||
stateChecker: "anotherStateChecker"
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* Multiple clients per session scenario:
|
||||
* - Displays sessions where each session has multiple associated clients.
|
||||
*/
|
||||
export const MultipleClientsSession: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
sessions: {
|
||||
sessions: [
|
||||
{
|
||||
expires: "2024-04-26T18:14:19Z",
|
||||
clients: ["account", "admin-console", "another-client"],
|
||||
ipAddress: "172.20.0.1",
|
||||
started: "2024-04-26T08:14:19Z",
|
||||
lastAccess: "2024-04-26T08:30:54Z",
|
||||
id: "multiple-clients-session"
|
||||
}
|
||||
]
|
||||
},
|
||||
stateChecker: "multiClientsStateChecker"
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
/**
|
||||
* Session without client details scenario:
|
||||
* - Simulates a session where no client information is provided.
|
||||
*/
|
||||
export const SessionWithoutClients: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
sessions: {
|
||||
sessions: [
|
||||
{
|
||||
expires: "2024-04-26T18:14:19Z",
|
||||
clients: [], // No clients information
|
||||
ipAddress: "172.20.0.1",
|
||||
started: "2024-04-26T08:14:19Z",
|
||||
lastAccess: "2024-04-26T08:30:54Z",
|
||||
id: "no-clients-session"
|
||||
}
|
||||
]
|
||||
},
|
||||
stateChecker: "noClientsStateChecker"
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
@ -180,3 +180,64 @@ export const MoreThanOneTotpProviders: Story = {
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
// TOTP Enabled but No Existing OTP Credentials
|
||||
export const TotpEnabledNoOtpCredentials: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
totp: {
|
||||
enabled: true,
|
||||
totpSecretEncoded: "HE4W MSTC OBKU CY2M",
|
||||
otpCredentials: [] // No OTP Credentials
|
||||
},
|
||||
stateChecker: "stateChecker123",
|
||||
url: {
|
||||
totpUrl: "http://localhost:8080/realms/myrealm/account/totp"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
// Manual Mode TOTP without Scanning
|
||||
export const ManualModeTotp: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
mode: "manual", // Manual mode
|
||||
totp: {
|
||||
enabled: false,
|
||||
totpSecretEncoded: "HE4W MSTC OBKU CY2M",
|
||||
otpCredentials: []
|
||||
},
|
||||
stateChecker: "stateChecker123",
|
||||
url: {
|
||||
totpUrl: "http://localhost:8080/realms/myrealm/account/totp"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
// Multiple OTP Devices Scenario
|
||||
export const MultipleOtpDevices: Story = {
|
||||
render: () => (
|
||||
<KcPageStory
|
||||
kcContext={{
|
||||
totp: {
|
||||
enabled: true,
|
||||
totpSecretEncoded: "G55E MZKC JFUD",
|
||||
otpCredentials: [
|
||||
{ id: "1", userLabel: "Phone 1" },
|
||||
{ id: "2", userLabel: "Tablet" }
|
||||
]
|
||||
},
|
||||
stateChecker: "stateChecker123",
|
||||
url: {
|
||||
totpUrl: "http://localhost:8080/realms/myrealm/account/totp"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user