Skip to content

Commit

Permalink
Merge pull request #3076 from glific/fix/multiple-profiles
Browse files Browse the repository at this point in the history
Fixed multiple profile issue
  • Loading branch information
kurund authored Sep 10, 2024
2 parents 39339ef + f481aad commit 7e2772e
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 71 deletions.
8 changes: 7 additions & 1 deletion src/containers/Form/FormLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ export const FormLayout = ({
}
}, [advanceSearch]);

useEffect(() => {
if (entityId) {
refetch();
}
}, [entityId]);

const capitalListItemName = listItemName[0].toUpperCase() + listItemName.slice(1);
let item: any = null;

Expand Down Expand Up @@ -221,7 +227,7 @@ export const FormLayout = ({
variables = params.type ? { shortcode: params.type } : false;
}

const { loading, error } = useQuery(getItemQuery, {
const { loading, error, refetch } = useQuery(getItemQuery, {
variables,
skip: !itemId,
fetchPolicy: getQueryFetchPolicy,
Expand Down
75 changes: 57 additions & 18 deletions src/containers/Profile/Contact/ContactProfile.test.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,26 @@
import { render, waitFor } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import { vi } from 'vitest';

import { LOGGED_IN_USER_MOCK } from 'mocks/Contact';
import { LOGGED_IN_USER_MOCK, multiple_profile_mock } from 'mocks/Contact';
import { ContactProfile } from './ContactProfile';
import { mocks as historyMock } from './ContactHistory/ContactHistory.test';
import { MemoryRouter } from 'react-router-dom';

vi.mock('react-router-dom', async () => {
const actual: any = await vi.importActual('react-router-dom');
return {
...actual,
useParams: () => ({ id: '1' }),
};
});
import { MemoryRouter, Route, Routes } from 'react-router-dom';

describe('contact profile', () => {
describe('contact profile with single profile', () => {
const mocks = [...LOGGED_IN_USER_MOCK, ...historyMock];

const contactProfile = (
<MemoryRouter>
<MemoryRouter initialEntries={['/contact-profile/1']}>
<MockedProvider mocks={mocks} addTypename={false}>
<ContactProfile />
<Routes>
<Route path="contact-profile/:id/*" element={<ContactProfile />} />
</Routes>
</MockedProvider>
</MemoryRouter>
);

test('contact profile should render', async () => {
const { getByText, getAllByRole } = render(contactProfile);
await waitFor(() => {
expect(getByText('Profile')).toBeInTheDocument();
});

await waitFor(() => {
expect(getByText('Loading...')).toBeInTheDocument();
Expand All @@ -44,5 +34,54 @@ describe('contact profile', () => {
await waitFor(() => {
expect(getAllByRole('textbox')[0]).toHaveValue('N/A');
});

fireEvent.click(getByText('History'));

await waitFor(() => {
expect(screen.getByText('Removed from collection: "Optout contacts"')).toBeInTheDocument();
});

fireEvent.click(getByText('Details'));

await waitFor(() => {
expect(screen.getByText('Status')).toBeInTheDocument();
expect(screen.getByText('Collections')).toBeInTheDocument();
});
});
});

describe('contact profile with no profiles', () => {
const wrapper = (
<MockedProvider mocks={multiple_profile_mock}>
<MemoryRouter initialEntries={['/contact-profile/2']}>
<Routes>
<Route path="contact-profile/:id/*" element={<ContactProfile />} />
</Routes>
</MemoryRouter>
</MockedProvider>
);

test('should switch profile', async () => {
render(wrapper);

await waitFor(() => {
expect(screen.getByText('Contact Profile')).toBeInTheDocument();
});

await waitFor(() => {
expect(screen.getByText('Loading...')).toBeInTheDocument();
});

//should show active profile first
await waitFor(() => {
expect(screen.getAllByRole('textbox')[0]).toHaveValue('profile name 2');
});

fireEvent.click(screen.getAllByTestId('profileHeader')[1]);

//should show active profile first
await waitFor(() => {
expect(screen.getAllByRole('textbox')[0]).toHaveValue('profile name 1');
});
});
});
6 changes: 2 additions & 4 deletions src/containers/Profile/Contact/ContactProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { useTranslation } from 'react-i18next';
import CollapseIcon from '../../../assets/images/icons/Collapse.svg?react';
import ExpandIcon from '../../../assets/images/icons/Expand.svg?react';
import { getContactStatus, getDisplayName } from 'common/utils';
import { getOrganizationServices } from 'services/AuthService';
import { GET_CONTACT_DETAILS, GET_CONTACT_PROFILES } from 'graphql/queries/Contact';
import { Loading } from 'components/UI/Layout/Loading/Loading';
import { AvatarDisplay } from 'components/UI/AvatarDisplay/AvatarDisplay';
Expand All @@ -23,12 +22,10 @@ export const ContactProfile = () => {
const [showProfileSection, setShowProfileSection] = useState('profile');
const { t } = useTranslation();

const isContactProfileEnabled = getOrganizationServices('contactProfileEnabled');
const { loading, data } = useQuery(GET_CONTACT_DETAILS, { variables: { id: params.id } });

const { loading: profileLoading, data: profileData } = useQuery(GET_CONTACT_PROFILES, {
variables: { filter: { contactId: params.id } },
skip: !isContactProfileEnabled,
fetchPolicy: 'network-only',
});

Expand All @@ -54,7 +51,7 @@ export const ContactProfile = () => {

let selectedProfile;

if (isContactProfileEnabled && profileData && profileData.profiles.length > 0) {
if (profileData && profileData.profiles.length > 0) {
selectedProfile = profileData.profiles.filter(
(profile: any) => profile.id === selectedProfileId
);
Expand Down Expand Up @@ -105,6 +102,7 @@ export const ContactProfile = () => {
return (
<React.Fragment key={id}>
<div
data-testid="profileHeader"
className={styles.ProfileHeader}
onClick={() => {
setSelectedProfileId(`${id}`);
Expand Down
29 changes: 15 additions & 14 deletions src/containers/Profile/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ import { CONTACT_STATUS, PROVIDER_STATUS } from 'common/constants';
import { FormLayout } from 'containers/Form/FormLayout';
import { Input } from 'components/UI/Form/Input/Input';
import { Loading } from 'components/UI/Layout/Loading/Loading';
import { GET_CONTACT } from 'graphql/queries/Contact';
import { GET_CONTACT, GET_PROFILE } from 'graphql/queries/Contact';
import {
CREATE_CONTACT,
UPDATE_CONTACT,
DELETE_CONTACT,
DELETE_CONTACT_PROFILE,
} from 'graphql/mutations/Contact';
import { GET_CURRENT_USER } from 'graphql/queries/User';
import { getOrganizationServices } from 'services/AuthService';
import { getDisplayName, isSimulator } from 'common/utils';
import { AutoComplete } from 'components/UI/Form/AutoComplete/AutoComplete';

Expand All @@ -43,11 +42,10 @@ export const Profile = ({
const [languageId, setLanguageId] = useState('');
const [hideRemoveBtn, setHideRemoveBtn] = useState(false);
const { t } = useTranslation();
const isContactProfileEnabled = getOrganizationServices('contactProfileEnabled');
const hasMultipleProfiles = multiProfileAttributes?.selectedProfile;

const queries = {
getItemQuery: GET_CONTACT,
getItemQuery: hasMultipleProfiles ? GET_PROFILE : GET_CONTACT,
createItemQuery: CREATE_CONTACT,
updateItemQuery: UPDATE_CONTACT,
deleteItemQuery: hasMultipleProfiles ? DELETE_CONTACT_PROFILE : DELETE_CONTACT,
Expand All @@ -58,16 +56,12 @@ export const Profile = ({
const { data, loading } = useQuery(GET_CURRENT_USER);

const updateName = () => {
if (!isContactProfileEnabled || !hasMultipleProfiles) {
if (!hasMultipleProfiles) {
return;
}
const { selectedProfile } = multiProfileAttributes;
const { selectedProfile, selectedProfileId } = multiProfileAttributes;

if (!selectedProfile) {
return;
}

if (selectedProfile.id === multiProfileAttributes.activeProfileId) {
if (selectedProfileId === multiProfileAttributes.activeProfileId) {
setName(`${selectedProfile.name} (currently active)`);
} else {
setName(selectedProfile.name);
Expand Down Expand Up @@ -103,6 +97,7 @@ export const Profile = ({
bspStatus: bspStatusValue,
language: languageIdValue,
fields: fieldsValue,
contact: contactDetails,
}: any) => {
updateName();
let hideDeleteButton = false;
Expand All @@ -126,9 +121,15 @@ export const Profile = ({
hideDeleteButton = organizationPhone === currentUserPhone;
}

if (hasMultipleProfiles) {
setStatus(contactDetails?.status);
setBspStatus(contactDetails?.bspStatus);
} else {
setStatus(statusValue);
setBspStatus(bspStatusValue);
}

setName(displayName);
setStatus(statusValue);
setBspStatus(bspStatusValue);
setHideRemoveBtn(hideDeleteButton);
setLanguageId(languageIdValue.id);
};
Expand Down Expand Up @@ -199,7 +200,7 @@ export const Profile = ({
dialogMessage={dialogMessage}
formFields={formFields}
redirectionLink={redirectionLink}
listItem="contact"
listItem={hasMultipleProfiles ? 'profile' : 'contact'}
icon={profileIcon}
afterDelete={afterDelete}
type={type}
Expand Down
22 changes: 22 additions & 0 deletions src/graphql/queries/Contact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,25 @@ export const GET_CONTACT_PROFILES = gql`
}
}
`;

export const GET_PROFILE = gql`
query getProfile($id: ID!) {
profile(id: $id) {
profile {
id
name
fields
type
language {
label
id
}
contact {
status
bspStatus
settings
}
}
}
}
`;
Loading

0 comments on commit 7e2772e

Please sign in to comment.