New Users IdP linking account tests (#3146)
This commit is contained in:
parent
a1140191d6
commit
4f25c71eed
5 changed files with 376 additions and 3 deletions
|
@ -3,13 +3,15 @@ import LoginPage from "../support/pages/LoginPage";
|
|||
import CreateUserPage from "../support/pages/admin_console/manage/users/CreateUserPage";
|
||||
import Masthead from "../support/pages/admin_console/Masthead";
|
||||
import ListingPage from "../support/pages/admin_console/ListingPage";
|
||||
import UserDetailsPage from "../support/pages/admin_console/manage/users/UserDetailsPage";
|
||||
import UserDetailsPage from "../support/pages/admin_console/manage/users/user_details/UserDetailsPage";
|
||||
import AttributesTab from "../support/pages/admin_console/manage/AttributesTab";
|
||||
import ModalUtils from "../support/util/ModalUtils";
|
||||
import { keycloakBefore } from "../support/util/keycloak_hooks";
|
||||
import UserGroupsPage from "../support/pages/admin_console/manage/users/UserGroupsPage";
|
||||
import adminClient from "../support/util/AdminClient";
|
||||
import CredentialsPage from "../support/pages/admin_console/manage/users/CredentialsPage";
|
||||
import UsersPage from "cypress/support/pages/admin_console/manage/users/UsersPage";
|
||||
import IdentityProviderLinksTab from "cypress/support/pages/admin_console/manage/users/user_details/tabs/IdentityProviderLinksTab";
|
||||
|
||||
let groupName = "group";
|
||||
let groupsList: string[] = [];
|
||||
|
@ -25,6 +27,8 @@ describe("User creation", () => {
|
|||
const userDetailsPage = new UserDetailsPage();
|
||||
const credentialsPage = new CredentialsPage();
|
||||
const attributesTab = new AttributesTab();
|
||||
const usersPage = new UsersPage();
|
||||
const identityProviderLinksTab = new IdentityProviderLinksTab();
|
||||
|
||||
let itemId = "user_crud";
|
||||
let itemIdWithGroups = "user_with_groups_crud";
|
||||
|
@ -37,7 +41,6 @@ describe("User creation", () => {
|
|||
adminClient.createGroup(groupName);
|
||||
groupsList = [...groupsList, groupName];
|
||||
}
|
||||
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
});
|
||||
|
@ -207,6 +210,129 @@ describe("User creation", () => {
|
|||
cy.findByTestId("empty-state").contains("No consents");
|
||||
});
|
||||
|
||||
describe("Identity provider links", () => {
|
||||
const usernameIdpLinksTest = "user_idp_link_test";
|
||||
const identityProviders = [
|
||||
{ testName: "Bitbucket", displayName: "BitBucket", alias: "bitbucket" },
|
||||
{ testName: "Facebook", displayName: "Facebook", alias: "facebook" },
|
||||
{
|
||||
testName: "Keycloak-oidc",
|
||||
displayName: "Keycloak OpenID Connect",
|
||||
alias: "keycloak-oidc",
|
||||
},
|
||||
];
|
||||
|
||||
before(async () => {
|
||||
await Promise.all([
|
||||
adminClient.createUser({
|
||||
username: usernameIdpLinksTest,
|
||||
enabled: true,
|
||||
}),
|
||||
identityProviders.forEach((idp) =>
|
||||
adminClient.createIdentityProvider(idp.displayName, idp.alias)
|
||||
),
|
||||
]);
|
||||
});
|
||||
|
||||
after(() => adminClient.deleteUser(usernameIdpLinksTest));
|
||||
|
||||
beforeEach(() => {
|
||||
usersPage.goToUserListTab().goToUserDetailsPage(usernameIdpLinksTest);
|
||||
userDetailsPage.goToIdentityProviderLinksTab();
|
||||
});
|
||||
|
||||
identityProviders.forEach(($idp, linkedIdpsCount) => {
|
||||
it(`Link account to IdP: ${$idp.testName}`, () => {
|
||||
const availableIdpsCount = identityProviders.length - linkedIdpsCount;
|
||||
|
||||
if (linkedIdpsCount == 0) {
|
||||
identityProviderLinksTab.assertNoIdentityProvidersLinkedMessageExist(
|
||||
true
|
||||
);
|
||||
}
|
||||
identityProviderLinksTab
|
||||
.assertAvailableIdentityProvidersItemsEqual(availableIdpsCount)
|
||||
.clickLinkAccount($idp.testName)
|
||||
.assertLinkAccountModalTitleEqual($idp.testName)
|
||||
.assertLinkAccountModalIdentityProviderInputEqual($idp.testName)
|
||||
.typeLinkAccountModalUserId("testUserId")
|
||||
.typeLinkAccountModalUsername("testUsername")
|
||||
.clickLinkAccountModalLinkBtn()
|
||||
.assertNotificationIdentityProviderLinked()
|
||||
.assertLinkedIdentityProvidersItemsEqual(linkedIdpsCount + 1)
|
||||
.assertAvailableIdentityProvidersItemsEqual(availableIdpsCount - 1)
|
||||
.assertLinkedIdentityProviderExist($idp.testName, true)
|
||||
.assertAvailableIdentityProviderExist($idp.testName, false);
|
||||
if (availableIdpsCount - 1 == 0) {
|
||||
identityProviderLinksTab.assertNoAvailableIdentityProvidersMessageExist(
|
||||
true
|
||||
);
|
||||
}
|
||||
masthead.closeAllAlertMessages();
|
||||
});
|
||||
});
|
||||
|
||||
it("Link account to already added IdP fail", () => {
|
||||
cy.wrap(null).then(() =>
|
||||
adminClient.unlinkAccountIdentityProvider(
|
||||
usernameIdpLinksTest,
|
||||
identityProviders[0].displayName
|
||||
)
|
||||
);
|
||||
|
||||
sidebarPage.goToUsers();
|
||||
usersPage.goToUserListTab().goToUserDetailsPage(usernameIdpLinksTest);
|
||||
userDetailsPage.goToIdentityProviderLinksTab();
|
||||
|
||||
cy.wrap(null).then(() =>
|
||||
adminClient.linkAccountIdentityProvider(
|
||||
usernameIdpLinksTest,
|
||||
identityProviders[0].displayName
|
||||
)
|
||||
);
|
||||
|
||||
identityProviderLinksTab
|
||||
.clickLinkAccount(identityProviders[0].testName)
|
||||
.assertLinkAccountModalTitleEqual(identityProviders[0].testName)
|
||||
.assertLinkAccountModalIdentityProviderInputEqual(
|
||||
identityProviders[0].testName
|
||||
)
|
||||
.typeLinkAccountModalUserId("testUserId")
|
||||
.typeLinkAccountModalUsername("testUsername")
|
||||
.clickLinkAccountModalLinkBtn()
|
||||
.assertNotificationAlreadyLinkedError();
|
||||
modalUtils.cancelModal();
|
||||
});
|
||||
|
||||
identityProviders.forEach(($idp, availableIdpsCount) => {
|
||||
it(`Unlink account from IdP: ${$idp.testName}`, () => {
|
||||
const linkedIdpsCount = identityProviders.length - availableIdpsCount;
|
||||
|
||||
if (availableIdpsCount == 0) {
|
||||
identityProviderLinksTab.assertNoAvailableIdentityProvidersMessageExist(
|
||||
true
|
||||
);
|
||||
}
|
||||
identityProviderLinksTab
|
||||
.assertAvailableIdentityProvidersItemsEqual(availableIdpsCount)
|
||||
.clickUnlinkAccount($idp.testName)
|
||||
.assertUnLinkAccountModalTitleEqual($idp.testName)
|
||||
.clickUnlinkAccountModalUnlinkBtn()
|
||||
.assertNotificationPoviderLinkRemoved()
|
||||
.assertLinkedIdentityProvidersItemsEqual(linkedIdpsCount - 1)
|
||||
.assertAvailableIdentityProvidersItemsEqual(availableIdpsCount + 1)
|
||||
.assertLinkedIdentityProviderExist($idp.testName, false)
|
||||
.assertAvailableIdentityProviderExist($idp.testName, true);
|
||||
if (linkedIdpsCount - 1 == 0) {
|
||||
identityProviderLinksTab.assertNoIdentityProvidersLinkedMessageExist(
|
||||
true
|
||||
);
|
||||
}
|
||||
masthead.closeAllAlertMessages();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Reset credential of User with empty state", () => {
|
||||
listingPage.goToItemDetails(itemId);
|
||||
credentialsPage
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import PageObject from "../../components/PageObject";
|
||||
import ListingPage from "../../ListingPage";
|
||||
|
||||
const listingPage = new ListingPage();
|
||||
|
||||
export default class UsersPage extends PageObject {
|
||||
private userListTabLink = "listTab";
|
||||
private permissionsTabLink = "permissionsTab";
|
||||
|
||||
public goToUserListTab() {
|
||||
cy.findByTestId(this.userListTabLink).click();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public goToPermissionsTab() {
|
||||
cy.findByTestId(this.permissionsTabLink).click();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public goToUserDetailsPage(username: string) {
|
||||
listingPage.searchItem(username);
|
||||
listingPage.goToItemDetails(username);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import { RequiredActionAlias } from "@keycloak/keycloak-admin-client/lib/defs/requiredActionProviderRepresentation";
|
||||
import PageObject from "../../../components/PageObject";
|
||||
|
||||
export default class UserDetailsPage {
|
||||
export default class UserDetailsPage extends PageObject {
|
||||
saveBtn: string;
|
||||
cancelBtn: string;
|
||||
emailInput: string;
|
||||
|
@ -12,8 +13,10 @@ export default class UserDetailsPage {
|
|||
enabledSwitch: string;
|
||||
enabledValue: boolean;
|
||||
requiredUserActions: RequiredActionAlias[];
|
||||
identityProviderLinksTab: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.saveBtn = "save-user";
|
||||
this.cancelBtn = "cancel-create-user";
|
||||
this.emailInput = "email-input";
|
||||
|
@ -29,6 +32,15 @@ export default class UserDetailsPage {
|
|||
this.enabledSwitch = "user-enabled-switch";
|
||||
this.enabledValue = true;
|
||||
this.requiredUserActions = [RequiredActionAlias.UPDATE_PASSWORD];
|
||||
this.identityProviderLinksTab = "identity-provider-links-tab";
|
||||
}
|
||||
|
||||
public goToIdentityProviderLinksTab() {
|
||||
cy.findByTestId(this.identityProviderLinksTab).click();
|
||||
cy.intercept("/admin/realms/master").as("load");
|
||||
cy.wait(["@load"]);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
fillUserData() {
|
|
@ -0,0 +1,162 @@
|
|||
import Masthead from "cypress/support/pages/admin_console/Masthead";
|
||||
import ModalUtils from "cypress/support/util/ModalUtils";
|
||||
|
||||
const modalUtils = new ModalUtils();
|
||||
const masthead = new Masthead();
|
||||
|
||||
export default class IdentityProviderLinksTab {
|
||||
private linkedProvidersSection = ".kc-linked-idps";
|
||||
private availableProvidersSection = ".kc-available-idps";
|
||||
private linkAccountBtn = ".pf-c-button.pf-m-link";
|
||||
private linkAccountModalIdentityProviderInput = "idpNameInput";
|
||||
private linkAccountModalUserIdInput = "userIdInput";
|
||||
private linkAccountModalUsernameInput = "usernameInput";
|
||||
private linkAccountModalLinkBtn = "Link";
|
||||
|
||||
public clickLinkAccount(idpName: string) {
|
||||
cy.get(this.availableProvidersSection + " tr")
|
||||
.contains(idpName)
|
||||
.parent()
|
||||
.find(this.linkAccountBtn)
|
||||
.click();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public clickUnlinkAccount(idpName: string) {
|
||||
cy.get(this.linkedProvidersSection + " tr")
|
||||
.contains(idpName)
|
||||
.parent()
|
||||
.parent()
|
||||
.find(this.linkAccountBtn)
|
||||
.click();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public typeLinkAccountModalUserId(userId: string) {
|
||||
cy.findByTestId(this.linkAccountModalUserIdInput).type(userId);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public typeLinkAccountModalUsername(username: string) {
|
||||
cy.findByTestId(this.linkAccountModalUsernameInput).type(username);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public clickLinkAccountModalLinkBtn() {
|
||||
cy.findByTestId(this.linkAccountModalLinkBtn).click();
|
||||
cy.intercept("/admin/realms/master").as("load");
|
||||
cy.wait(["@load"]);
|
||||
return this;
|
||||
}
|
||||
|
||||
public clickUnlinkAccountModalUnlinkBtn() {
|
||||
modalUtils.confirmModal();
|
||||
cy.intercept("/admin/realms/master").as("load");
|
||||
cy.wait(["@load"]);
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertNoIdentityProvidersLinkedMessageExist(exist: boolean) {
|
||||
cy.get(this.linkedProvidersSection).should(
|
||||
(exist ? "" : "not.") + "contain.text",
|
||||
"No identity providers linked. Choose one from the list below."
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertNoAvailableIdentityProvidersMessageExist(exist: boolean) {
|
||||
cy.get(this.availableProvidersSection).should(
|
||||
(exist ? "" : "not.") + "contain.text",
|
||||
"No available identity providers."
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertLinkAccountModalTitleEqual(idpName: string) {
|
||||
modalUtils.assertModalTitleEqual(`Link account to ${idpName}`);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertUnLinkAccountModalTitleEqual(idpName: string) {
|
||||
modalUtils.assertModalTitleEqual(`Unlink account from ${idpName}?`);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertLinkAccountModalIdentityProviderInputEqual(idpName: string) {
|
||||
cy.findByTestId(this.linkAccountModalIdentityProviderInput).should(
|
||||
"have.value",
|
||||
idpName
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertNotificationIdentityProviderLinked() {
|
||||
masthead.checkNotificationMessage("Identity provider has been linked");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertNotificationAlreadyLinkedError() {
|
||||
masthead.checkNotificationMessage(
|
||||
"Could not link identity provider User is already linked with provider"
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertNotificationPoviderLinkRemoved() {
|
||||
masthead.checkNotificationMessage("The provider link has been removed");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertLinkedIdentityProvidersItemsEqual(count: number) {
|
||||
if (count > 0) {
|
||||
cy.get(this.linkedProvidersSection + " tbody")
|
||||
.find("tr")
|
||||
.should("have.length", count);
|
||||
} else {
|
||||
cy.get(this.linkedProvidersSection + " tbody").should("not.exist");
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertAvailableIdentityProvidersItemsEqual(count: number) {
|
||||
if (count > 0) {
|
||||
cy.get(this.availableProvidersSection + " tbody")
|
||||
.find("tr")
|
||||
.should("have.length", count);
|
||||
} else {
|
||||
cy.get(this.availableProvidersSection + " tbody").should("not.exist");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertLinkedIdentityProviderExist(idpName: string, exist: boolean) {
|
||||
cy.get(this.linkedProvidersSection).should(
|
||||
(exist ? "" : "not.") + "contain.text",
|
||||
idpName
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public assertAvailableIdentityProviderExist(idpName: string, exist: boolean) {
|
||||
cy.get(this.availableProvidersSection).should(
|
||||
(exist ? "" : "not.") + "contain.text",
|
||||
idpName
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -184,6 +184,51 @@ class AdminClient {
|
|||
await this.login();
|
||||
return await this.client.roles.delByName({ name });
|
||||
}
|
||||
|
||||
async createIdentityProvider(idpDisplayName: string, alias: string) {
|
||||
await this.login();
|
||||
const identityProviders =
|
||||
(await this.client.serverInfo.find()).identityProviders || [];
|
||||
const idp = identityProviders.find(({ name }) => name === idpDisplayName);
|
||||
await this.client.identityProviders.create({
|
||||
providerId: idp?.id!,
|
||||
displayName: idpDisplayName,
|
||||
alias: alias,
|
||||
});
|
||||
}
|
||||
|
||||
async unlinkAccountIdentityProvider(
|
||||
username: string,
|
||||
idpDisplayName: string
|
||||
) {
|
||||
await this.login();
|
||||
const user = await this.client.users.find({ username });
|
||||
const identityProviders =
|
||||
(await this.client.serverInfo.find()).identityProviders || [];
|
||||
const idp = identityProviders.find(({ name }) => name === idpDisplayName);
|
||||
await this.client.users.delFromFederatedIdentity({
|
||||
id: user[0].id!,
|
||||
federatedIdentityId: idp?.id!,
|
||||
});
|
||||
}
|
||||
|
||||
async linkAccountIdentityProvider(username: string, idpDisplayName: string) {
|
||||
await this.login();
|
||||
const user = await this.client.users.find({ username });
|
||||
const identityProviders =
|
||||
(await this.client.serverInfo.find()).identityProviders || [];
|
||||
const idp = identityProviders.find(({ name }) => name === idpDisplayName);
|
||||
const fedIdentity = {
|
||||
identityProvider: idp?.id,
|
||||
userId: "testUserIdApi",
|
||||
userName: "testUserNameApi",
|
||||
};
|
||||
await this.client.users.addToFederatedIdentity({
|
||||
id: user[0].id!,
|
||||
federatedIdentityId: idp?.id!,
|
||||
federatedIdentity: fedIdentity,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const adminClient = new AdminClient();
|
||||
|
|
Loading…
Reference in a new issue