diff --git a/packages/fhir-keycloak-user-management/src/components/UserList/Viewdetails/ViewDetailResources/tests/fixtures.ts b/packages/fhir-keycloak-user-management/src/components/UserList/Viewdetails/ViewDetailResources/tests/fixtures.ts
index 1d543f159..d4b5bb55e 100644
--- a/packages/fhir-keycloak-user-management/src/components/UserList/Viewdetails/ViewDetailResources/tests/fixtures.ts
+++ b/packages/fhir-keycloak-user-management/src/components/UserList/Viewdetails/ViewDetailResources/tests/fixtures.ts
@@ -206,6 +206,33 @@ export const user1147 = {
},
};
+export const user1147ExtraFields = {
+ id: '9f72c646-dc1e-4f24-98df-6f04373b9ec6',
+ createdTimestamp: 1675179889477,
+ username: '1147',
+ enabled: true,
+ totp: false,
+ emailVerified: false,
+ firstName: 'test1147',
+ lastName: '1147',
+ email: 'mejay2303@gmail.com',
+ attributes: {
+ fhir_core_app_id: ['giz'],
+ nationalId: ['1234567891011121'],
+ phoneNumber: ['0101345678'],
+ },
+ disableableCredentialTypes: [],
+ requiredActions: [],
+ notBefore: 1681810919,
+ access: {
+ manageGroupMembership: true,
+ view: true,
+ mapRoles: true,
+ impersonate: true,
+ manage: true,
+ },
+};
+
export const user1147Groups = [
{
id: 'b68e2590-c2ee-4b3c-9184-c4b35a69a271',
diff --git a/packages/fhir-keycloak-user-management/src/components/UserList/Viewdetails/tests/index.test.tsx b/packages/fhir-keycloak-user-management/src/components/UserList/Viewdetails/tests/index.test.tsx
index 8d5f7469d..271a854a2 100644
--- a/packages/fhir-keycloak-user-management/src/components/UserList/Viewdetails/tests/index.test.tsx
+++ b/packages/fhir-keycloak-user-management/src/components/UserList/Viewdetails/tests/index.test.tsx
@@ -25,6 +25,7 @@ import {
import {
practitionerDetailsBundle,
user1147,
+ user1147ExtraFields,
user1147Groups,
user1147Roles,
} from '../ViewDetailResources/tests/fixtures';
@@ -308,3 +309,166 @@ test('Edit button works correctly', async () => {
expect(history.location.pathname).toEqual('/admin/users/edit/userId');
});
+
+test('Renders extra user fields correctly', async () => {
+ const history = createMemoryHistory();
+ history.push(`${URL_USER}/${userId}`);
+
+ const successMock = jest
+ .spyOn(notifications, 'sendSuccessNotification')
+ .mockImplementation(() => {
+ return;
+ });
+
+ nock(props.fhirBaseURL)
+ .get(`/${practitionerDetailsResourceType}/_search`)
+ .query({ 'keycloak-uuid': userId })
+ .reply(200, practitionerDetailsBundle);
+
+ nock(props.keycloakBaseURL)
+ .get(`${KEYCLOAK_URL_USERS}/${userId}`)
+ .reply(200, user1147ExtraFields);
+
+ nock(props.keycloakBaseURL)
+ .get(`${KEYCLOAK_URL_USERS}/${userId}${KEYCLOAK_URL_USER_GROUPS}`)
+ .reply(200, user1147Groups);
+
+ render(
+
+
+
+ );
+
+ // this only await the first call to get the users.
+ await waitForElementToBeRemoved(document.querySelector('.ant-spin'));
+
+ expect(screen.queryByTitle(/View details/i)).toBeInTheDocument();
+
+ // second page header details.
+ const userProfile = screen.getByTestId('user-profile');
+ const textContent = userProfile.textContent;
+ expect(textContent).toEqual(
+ '1147EnabledDeleteEditId9f72c646-dc1e-4f24-98df-6f04373b9ec6First Nametest1147Last Name1147National ID1234567891011121Phone Number0101345678Username1147Emailmejay2303@gmail.comVerifiedFalseAttributesfhir_core_app_id["giz"]'
+ );
+
+ // have a look at the tabs
+
+ // start with group
+ const groupTab = screen.getByText('User groups');
+ fireEvent.click(groupTab);
+
+ await waitForElementToBeRemoved(document.querySelector('.ant-spin'));
+
+ // check table has correct number of rows. and try removing user from one group
+ let detailsTabSection = document.querySelector('.details-tab');
+ const groupsTable = detailsTabSection?.querySelector('table');
+
+ const tableData = [...(groupsTable?.querySelectorAll('tr') ?? [])].map((tr) => tr.textContent);
+ expect(tableData).toEqual(['NamePathActions', 'SuperUser/SuperUserLeave']);
+
+ const leaveBtn = screen.getByText('Leave');
+ expect(leaveBtn).toMatchInlineSnapshot(`
+
+ Leave
+
+ `);
+
+ nock(props.keycloakBaseURL)
+ .delete(`${KEYCLOAK_URL_USERS}/${userId}${KEYCLOAK_URL_USER_GROUPS}/${user1147Groups[0].id}`)
+ .reply(200, user1147Groups);
+
+ fireEvent.click(leaveBtn);
+
+ await waitFor(() => {
+ expect(successMock).toHaveBeenCalledWith(
+ 'User has been successfully removed from the keycloak group'
+ );
+ });
+
+ // go to practitioners
+ const practTab = screen.getByText('Practitioners');
+ fireEvent.click(practTab);
+
+ // Check that practitioner-details has finished loading.
+ await waitFor(() => {
+ expect(screen.getByText('3a801d6e-7bd3-4a5f-bc9c-64758fbb3dad')).toBeInTheDocument();
+ });
+
+ // practitioner records
+ detailsTabSection = document.querySelector('div.ant-tabs-tabpane-active');
+ const practitionerTable = detailsTabSection?.querySelector('table');
+
+ const practitionerData = [...(practitionerTable?.querySelectorAll('tr') ?? [])].map(
+ (tr) => tr.textContent
+ );
+ expect(practitionerData).toEqual([
+ 'IdNameActiveUser TypePractitioner Role Coding',
+ '3a801d6e-7bd3-4a5f-bc9c-64758fbb3dadtest1147 1147ActivepractitionerAssigned practitioner(http://snomed.info/sct|405623001), ',
+ ]);
+
+ // go to roles
+ nock(props.keycloakBaseURL)
+ .get(`${KEYCLOAK_URL_USERS}/${userId}/${keycloakRoleMappingsEndpoint}`)
+ .reply(200, user1147Roles);
+
+ const rolesTab = screen.getByText('User roles');
+ fireEvent.click(rolesTab);
+
+ // Check that practitioner-details has finished loading.
+ await waitFor(() => {
+ expect(screen.getByText('GET_LOCATION')).toBeInTheDocument();
+ });
+
+ // practitioner records
+ detailsTabSection = document.querySelector('div.ant-tabs-tabpane-active');
+ const realmRolesTable = detailsTabSection?.querySelectorAll('table')[0];
+ const clientRolesTable = detailsTabSection?.querySelectorAll('table')[1];
+ const realmRolesData = [...(realmRolesTable?.querySelectorAll('tr') ?? [])].map(
+ (tr) => tr.textContent
+ );
+ const clientRolesData = [...(clientRolesTable?.querySelectorAll('tr') ?? [])].map(
+ (tr) => tr.textContent
+ );
+ expect(realmRolesData).toEqual([
+ 'NameDescription',
+ 'POST_LOCATION',
+ 'GET_LOCATION',
+ 'offline_access${role_offline-access}',
+ ]);
+
+ expect(clientRolesData).toEqual([
+ 'ClientNameDescription',
+ 'realm-managementmanage-realm${role_manage-realm}',
+ 'realm-managementmanage-users${role_manage-users}',
+ 'accountmanage-account${role_manage-account}',
+ ]);
+
+ // go to careTeams
+ const careTeamsTab = screen.getByText('CareTeams');
+ fireEvent.click(careTeamsTab);
+
+ // practitioner records
+ detailsTabSection = document.querySelector('div.ant-tabs-tabpane-active');
+ const careTeamsTable = detailsTabSection?.querySelector('table');
+
+ const careTeamsData = [...(careTeamsTable?.querySelectorAll('tr') ?? [])].map(
+ (tr) => tr.textContent
+ );
+ expect(careTeamsData).toEqual(['IdNameStatusCategory', 'No data']);
+
+ // go to organization
+ const organizationsTab = screen.getByText('Organizations');
+ fireEvent.click(organizationsTab);
+
+ // practitioner records
+ detailsTabSection = document.querySelector('div.ant-tabs-tabpane-active');
+ const organizationsTable = detailsTabSection?.querySelector('table');
+
+ const organizationsData = [...(organizationsTable?.querySelectorAll('tr') ?? [])].map(
+ (tr) => tr.textContent
+ );
+ expect(organizationsData).toEqual([
+ 'IdNameActiveType',
+ '0d7ae048-9b84-4f0c-ba37-8d6c0b97dc84e2e-corporationActive(http://terminology.hl7.org/CodeSystem/organization-type|team), ',
+ ]);
+});
diff --git a/packages/keycloak-user-management/src/components/forms/UserForm/utils.tsx b/packages/keycloak-user-management/src/components/forms/UserForm/utils.tsx
index 6d5d778d8..de2811be1 100644
--- a/packages/keycloak-user-management/src/components/forms/UserForm/utils.tsx
+++ b/packages/keycloak-user-management/src/components/forms/UserForm/utils.tsx
@@ -100,16 +100,8 @@ const createEditKeycloakUser = async (
keycloakBaseURL
);
- keycloakUserPayload.attributes = {
- ...keycloakUserPayload.attributes,
- nationalId: keycloakUserPayload.nationalId,
- phoneNumber: keycloakUserPayload.phoneNumber,
- };
-
- const { nationalId, phoneNumber, ...coreUserPayload } = keycloakUserPayload;
-
return serve
- .update(coreUserPayload)
+ .update(keycloakUserPayload)
.then(() => {
sendSuccessNotification(t('User edited successfully'));
updateGroupsAndPractitionerCallback(keycloakUserPayload.id).catch(() =>
@@ -120,18 +112,10 @@ const createEditKeycloakUser = async (
throw error;
});
} else {
- keycloakUserPayload.attributes = {
- ...keycloakUserPayload.attributes,
- nationalId: keycloakUserPayload.nationalId,
- phoneNumber: keycloakUserPayload.phoneNumber,
- };
-
- const { nationalId, phoneNumber, ...coreUserPayload } = keycloakUserPayload;
-
// create new keycloak user
const serve = new KeycloakService(KEYCLOAK_URL_USERS, keycloakBaseURL);
return serve
- .create(coreUserPayload)
+ .create(keycloakUserPayload)
.then((res) => {
sendSuccessNotification(t('User created successfully'));
const keycloakUserId = getUserId(res);
@@ -337,6 +321,8 @@ export const getUserAndGroupsPayload = (values: FormFields) => {
const preUserAttributes = {
...(contact ? { contact: [contact] } : {}),
...(fhirCoreAppId ? { fhir_core_app_id: [fhirCoreAppId] } : {}),
+ ...(nationalId ? { nationalId: [nationalId] } : {}),
+ ...(phoneNumber ? { phoneNumber: [phoneNumber] } : {}),
};
const cleanedAttributes = pickBy(
@@ -350,8 +336,6 @@ export const getUserAndGroupsPayload = (values: FormFields) => {
firstName,
id: isEditMode ? id : '', // id is generated by keycloak for after POST new user
lastName,
- nationalId,
- phoneNumber,
username,
...(email ? { email } : {}),
enabled,
diff --git a/packages/keycloak-user-management/src/ducks/user.ts b/packages/keycloak-user-management/src/ducks/user.ts
index 0d5c1a8fb..4c0bf4cd4 100644
--- a/packages/keycloak-user-management/src/ducks/user.ts
+++ b/packages/keycloak-user-management/src/ducks/user.ts
@@ -62,8 +62,8 @@ export interface KeycloakUser {
firstName: string;
id: string;
lastName: string;
- nationalId: string;
- phoneNumber: string;
+ nationalId?: string;
+ phoneNumber?: string;
notBefore?: number;
requiredActions?: string[];
totp?: boolean;