Updated the test ldap settings with second button (#1275)

Co-authored-by: Jon Koops <jonkoops@gmail.com>
This commit is contained in:
Erik Jan de Wit 2021-10-05 12:31:39 +02:00 committed by GitHub
parent fae250f13e
commit 9180b18652
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 106 additions and 39 deletions

View file

@ -1,13 +1,18 @@
/** /**
* @jest-environment jsdom * @jest-environment jsdom
*/ */
import { Button } from "@patternfly/react-core";
import { fireEvent, render, screen } from "@testing-library/react";
import type { ServerInfoRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation";
import React, { useState } from "react"; import React, { useState } from "react";
import { fireEvent, render, screen } from "@testing-library/react";
import { Button } from "@patternfly/react-core";
import type { ServerInfoRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation";
import type WhoAmIRepresentation from "@keycloak/keycloak-admin-client/lib/defs/whoAmIRepresentation";
import { ServerInfoContext } from "../../context/server-info/ServerInfoProvider"; import { ServerInfoContext } from "../../context/server-info/ServerInfoProvider";
import serverInfo from "../../context/server-info/__tests__/mock.json"; import serverInfo from "../../context/server-info/__tests__/mock.json";
import { AddMapperDialog, AddMapperDialogModalProps } from "./MapperDialog"; import { AddMapperDialog, AddMapperDialogModalProps } from "./MapperDialog";
import { WhoAmI, WhoAmIContext } from "../../context/whoami/WhoAmI";
import whoami from "../../context/whoami/__tests__/mock-whoami.json";
describe("MapperDialog", () => { describe("MapperDialog", () => {
const Test = (args: AddMapperDialogModalProps) => { const Test = (args: AddMapperDialogModalProps) => {
@ -17,12 +22,21 @@ describe("MapperDialog", () => {
<ServerInfoContext.Provider <ServerInfoContext.Provider
value={serverInfo as unknown as ServerInfoRepresentation} value={serverInfo as unknown as ServerInfoRepresentation}
> >
<AddMapperDialog <WhoAmIContext.Provider
{...args} value={{
open={open} refresh: () => {},
toggleDialog={() => setOpen(!open)} whoAmI: new WhoAmI(whoami as WhoAmIRepresentation),
/> }}
<Button onClick={() => setOpen(true)}>{!open ? "Show" : "Hide"}</Button> >
<AddMapperDialog
{...args}
open={open}
toggleDialog={() => setOpen(!open)}
/>
<Button onClick={() => setOpen(true)}>
{!open ? "Show" : "Hide"}
</Button>
</WhoAmIContext.Provider>
</ServerInfoContext.Provider> </ServerInfoContext.Provider>
); );
}; };
@ -59,7 +73,7 @@ describe("MapperDialog", () => {
render(<Test protocol={protocol} onConfirm={onConfirm} />); render(<Test protocol={protocol} onConfirm={onConfirm} />);
fireEvent.click(screen.getByText("Show")); fireEvent.click(screen.getByText("Show"));
fireEvent.click(screen.getByLabelText("User Realm Role")); fireEvent.click(screen.getByLabelText("Allowed Web Origins"));
expect(onConfirm).toBeCalledWith( expect(onConfirm).toBeCalledWith(
serverInfo.protocolMapperTypes[protocol][0] serverInfo.protocolMapperTypes[protocol][0]

View file

@ -1,4 +1,4 @@
import React, { useState } from "react"; import React, { useMemo, useState } from "react";
import { import {
Button, Button,
ButtonVariant, ButtonVariant,
@ -11,6 +11,7 @@ import {
ModalVariant, ModalVariant,
Text, Text,
TextContent, TextContent,
TextVariants,
} from "@patternfly/react-core"; } from "@patternfly/react-core";
import { import {
Table, Table,
@ -23,6 +24,7 @@ import type ProtocolMapperRepresentation from "@keycloak/keycloak-admin-client/l
import type { ProtocolMapperTypeRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation"; import type { ProtocolMapperTypeRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation";
import { useServerInfo } from "../../context/server-info/ServerInfoProvider"; import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
import { useWhoAmI } from "../../context/whoami/WhoAmI";
import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState"; import { ListEmptyState } from "../../components/list-empty-state/ListEmptyState";
export type AddMapperDialogModalProps = { export type AddMapperDialogModalProps = {
@ -42,21 +44,28 @@ export const AddMapperDialog = (props: AddMapperDialogProps) => {
const { t } = useTranslation("client-scopes"); const { t } = useTranslation("client-scopes");
const serverInfo = useServerInfo(); const serverInfo = useServerInfo();
const { whoAmI } = useWhoAmI();
const protocol = props.protocol; const protocol = props.protocol;
const protocolMappers = serverInfo.protocolMapperTypes![protocol]; const protocolMappers = serverInfo.protocolMapperTypes![protocol];
const builtInMappers = serverInfo.builtinProtocolMappers![protocol]; const builtInMappers = serverInfo.builtinProtocolMappers![protocol];
const [filter, setFilter] = useState<ProtocolMapperRepresentation[]>([]); const [filter, setFilter] = useState<ProtocolMapperRepresentation[]>([]);
const allRows = builtInMappers.map((mapper) => { const allRows = useMemo(
const mapperType = protocolMappers.filter( () =>
(type) => type.id === mapper.protocolMapper builtInMappers
)[0]; .sort((a, b) => a.name!.localeCompare(b.name!, whoAmI.getLocale()))
return { .map((mapper) => {
item: mapper, const mapperType = protocolMappers.filter(
selected: false, (type) => type.id === mapper.protocolMapper
cells: [mapper.name, mapperType.helpText], )[0];
}; return {
}); item: mapper,
selected: false,
cells: [mapper.name, mapperType.helpText],
};
}),
[]
);
const [rows, setRows] = useState(allRows); const [rows, setRows] = useState(allRows);
if (props.filter && props.filter.length !== filter.length) { if (props.filter && props.filter.length !== filter.length) {
@ -68,12 +77,29 @@ export const AddMapperDialog = (props: AddMapperDialogProps) => {
const selectedRows = rows const selectedRows = rows
.filter((row) => row.selected) .filter((row) => row.selected)
.map((row) => row.item); .map((row) => row.item);
const sortedProtocolMappers = useMemo(
() =>
protocolMappers.sort((a, b) =>
a.name!.localeCompare(b.name!, whoAmI.getLocale())
),
[protocolMappers]
);
const isBuiltIn = !!props.filter; const isBuiltIn = !!props.filter;
const header = [t("common:name"), t("common:description")];
return ( return (
<Modal <Modal
aria-labelledby={t("chooseAMapperType")}
variant={ModalVariant.medium} variant={ModalVariant.medium}
title={t("chooseAMapperType")} header={
<TextContent>
<Text component={TextVariants.h1}>{t("chooseAMapperType")}</Text>
<Text>{t("predefinedMappingDescription")}</Text>
</TextContent>
}
isOpen={props.open} isOpen={props.open}
onClose={props.toggleDialog} onClose={props.toggleDialog}
actions={ actions={
@ -105,9 +131,6 @@ export const AddMapperDialog = (props: AddMapperDialogProps) => {
: [] : []
} }
> >
<TextContent>
<Text>{t("predefinedMappingDescription")}</Text>
</TextContent>
{!isBuiltIn && ( {!isBuiltIn && (
<DataList <DataList
onSelectDataListItem={(id) => { onSelectDataListItem={(id) => {
@ -118,7 +141,18 @@ export const AddMapperDialog = (props: AddMapperDialogProps) => {
aria-label={t("chooseAMapperType")} aria-label={t("chooseAMapperType")}
isCompact isCompact
> >
{protocolMappers.map((mapper) => ( <DataListItem aria-labelledby="headerName" id="header">
<DataListItemRow>
<DataListItemCells
dataListCells={header.map((name) => (
<DataListCell style={{ fontWeight: 700 }} key={name}>
{name}
</DataListCell>
))}
/>
</DataListItemRow>
</DataListItem>
{sortedProtocolMappers.map((mapper) => (
<DataListItem <DataListItem
aria-label={mapper.name} aria-label={mapper.name}
key={mapper.id} key={mapper.id}
@ -143,7 +177,7 @@ export const AddMapperDialog = (props: AddMapperDialogProps) => {
{isBuiltIn && rows.length > 0 && ( {isBuiltIn && rows.length > 0 && (
<Table <Table
variant={TableVariant.compact} variant={TableVariant.compact}
cells={[t("common:name"), t("common:description")]} cells={header}
onSelect={(_, isSelected, rowIndex) => { onSelect={(_, isSelected, rowIndex) => {
rows[rowIndex].selected = isSelected; rows[rowIndex].selected = isSelected;
setRows([...rows]); setRows([...rows]);

View file

@ -49,6 +49,7 @@ export default {
enableHelpMode: "Enable help mode", enableHelpMode: "Enable help mode",
learnMore: "Learn more", learnMore: "Learn more",
test: "Test", test: "Test",
testConnection: "Test connection",
name: "Name", name: "Name",
role: "Role", role: "Role",
description: "Description", description: "Description",

View file

@ -50,7 +50,7 @@ export const AddUserEmailModal = ({
form="email-form" form="email-form"
isDisabled={!watchEmailInput} isDisabled={!watchEmailInput}
> >
{t("realm-settings:testConnection")} {t("common:testConnection")}
</Button>, </Button>,
<Button <Button
id="modal-cancel" id="modal-cancel"

View file

@ -390,7 +390,7 @@ export const RealmSettingsEmailTab = ({
!(emailRegexPattern.test(watchFromValue) && watchHostValue) !(emailRegexPattern.test(watchFromValue) && watchHostValue)
} }
> >
{t("realm-settings:testConnection")} {t("common:testConnection")}
</Button> </Button>
<Button variant="link" onClick={reset}> <Button variant="link" onClick={reset}>
{t("common:revert")} {t("common:revert")}

View file

@ -40,6 +40,19 @@ const testLdapProperties: Array<keyof TestLdapConnectionRepresentation> = [
"authType", "authType",
]; ];
type TestTypes = "testConnection" | "testAuthentication";
const convertFormToSettings = (form: UseFormMethods) => {
const settings: TestLdapConnectionRepresentation = {};
testLdapProperties.forEach((key) => {
const value = _.get(form.getValues(), `config.${key}`);
settings[key] = Array.isArray(value) ? value[0] : "";
});
return settings;
};
export const LdapSettingsConnection = ({ export const LdapSettingsConnection = ({
form, form,
showSectionHeading = false, showSectionHeading = false,
@ -52,17 +65,12 @@ export const LdapSettingsConnection = ({
const { realm } = useRealm(); const { realm } = useRealm();
const { addAlert, addError } = useAlerts(); const { addAlert, addError } = useAlerts();
const testLdap = async () => { const testLdap = async (testType: TestTypes) => {
try { try {
const settings: TestLdapConnectionRepresentation = {}; const settings = convertFormToSettings(form);
testLdapProperties.forEach((key) => {
const value = _.get(form.getValues(), `config.${key}`);
settings[key] = _.isArray(value) ? value[0] : "";
});
await adminClient.realms.testLDAPConnection( await adminClient.realms.testLDAPConnection(
{ realm }, { realm },
{ ...settings, action: "testConnection" } { ...settings, action: testType }
); );
addAlert(t("testSuccess"), AlertVariant.success); addAlert(t("testSuccess"), AlertVariant.success);
} catch (error) { } catch (error) {
@ -235,6 +243,15 @@ export const LdapSettingsConnection = ({
ref={form.register} ref={form.register}
/> />
</FormGroup> </FormGroup>
<FormGroup fieldId="kc-test-button">
<Button
variant="secondary"
id="kc-connection-test-button"
onClick={() => testLdap("testConnection")}
>
{t("common:testConnection")}
</Button>
</FormGroup>
<FormGroup <FormGroup
label={t("bindType")} label={t("bindType")}
labelIcon={ labelIcon={
@ -337,9 +354,9 @@ export const LdapSettingsConnection = ({
<Button <Button
variant="secondary" variant="secondary"
id="kc-test-button" id="kc-test-button"
onClick={() => testLdap()} onClick={() => testLdap("testAuthentication")}
> >
{t("common:test")} {t("testAuthentication")}
</Button> </Button>
</FormGroup> </FormGroup>
</FormAccess> </FormAccess>

View file

@ -90,6 +90,7 @@ export default {
saveError: "User federation provider could not be saved: {{error}}", saveError: "User federation provider could not be saved: {{error}}",
createSuccess: "User federation provider successfully created", createSuccess: "User federation provider successfully created",
createError: "User federation provider could not be created: {{error}}", createError: "User federation provider could not be created: {{error}}",
testAuthentication: "Test authentication",
testSuccess: "Successfully connected to LDAP", testSuccess: "Successfully connected to LDAP",
testError: testError:
"Error when trying to connect to LDAP. See server.log for details. {{error}}", "Error when trying to connect to LDAP. See server.log for details. {{error}}",