Skip to content

Commit

Permalink
Merge pull request #1177 from CruGlobal/8145-optional-street-address
Browse files Browse the repository at this point in the history
[MPDX-8145] Make address street optional
  • Loading branch information
canac authored Nov 6, 2024
2 parents 0b78e24 + 56e645f commit fd125c5
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,28 @@ describe('AddAddressModal', () => {
expect(handleClose).toHaveBeenCalled();
});

it('requires at least one field to be filled', async () => {
const { getByRole } = render(
<SnackbarProvider>
<ThemeProvider theme={theme}>
<GqlMockedProvider>
<AddAddressModal
accountListId={accountListId}
contactId={contactId}
handleClose={handleClose}
/>
</GqlMockedProvider>
</ThemeProvider>
</SnackbarProvider>,
);

const saveButton = getByRole('button', { name: 'Save' });
await waitFor(() => expect(saveButton).toBeDisabled());

userEvent.type(getByRole('textbox', { name: 'City' }), 'City');
await waitFor(() => expect(saveButton).not.toBeDisabled());
});

it('should create contact address', async () => {
const mutationSpy = jest.fn();
const newStreet = '4321 Neat Street';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
CancelButton,
SubmitButton,
} from 'src/components/common/Modal/ActionButtons/ActionButtons';
import { AddressCreateInput } from 'src/graphql/types.generated';
import { useUpdateCache } from 'src/hooks/useUpdateCache';
import Modal from '../../../../../common/Modal/Modal';
import {
Expand All @@ -35,8 +34,8 @@ import {
} from '../AddressLocation';
import { useSetContactPrimaryAddressMutation } from '../SetPrimaryAddress.generated';
import { StreetAutocomplete } from '../StreetAutocomplete/StreetAutocomplete';
import { AddressSchema, addressSchema } from '../addressSchema';
import { useCreateContactAddressMutation } from './CreateContactAddress.generated';
import { createAddressSchema } from './createAddressSchema';

const ContactEditContainer = styled(Box)(({ theme }) => ({
display: 'flex',
Expand Down Expand Up @@ -78,21 +77,24 @@ export const AddAddressModal: React.FC<EditContactAddressModalProps> = ({

const onSubmit = async ({
primaryMailingAddress,
street,
...attributes
}: Omit<AddressCreateInput, 'validValues'> & {
primaryMailingAddress: boolean;
}) => {
}: AddressSchema) => {
const response = await createContactAddress({
variables: {
accountListId,
attributes,
attributes: {
contactId,
street: street ?? '',
...attributes,
},
},
update: (cache, { data: createdAddressData }) => {
if (handleUpdateCache) {
handleUpdateCache(cache, {
createAddress: {
address: createdAddressData?.createAddress?.address,
contactId: attributes.contactId,
contactId,
},
});
} else {
Expand Down Expand Up @@ -137,14 +139,13 @@ export const AddAddressModal: React.FC<EditContactAddressModalProps> = ({
enqueueSnackbar(t('Address added successfully'), {
variant: 'success',
});
await handleClose();
handleClose();
};

return (
<Modal isOpen={true} title={t('Add Address')} handleClose={handleClose}>
<Formik
initialValues={{
contactId,
city: '',
country: '',
historic: false,
Expand All @@ -156,7 +157,7 @@ export const AddAddressModal: React.FC<EditContactAddressModalProps> = ({
street: '',
primaryMailingAddress: true,
}}
validationSchema={createAddressSchema}
validationSchema={addressSchema}
validateOnMount
onSubmit={onSubmit}
>
Expand Down Expand Up @@ -201,7 +202,6 @@ export const AddAddressModal: React.FC<EditContactAddressModalProps> = ({
TextFieldProps={{
name: 'street',
label: t('Street'),
required: true,
fullWidth: true,
}}
/>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,47 @@ describe('EditContactAddressModal', () => {
expect(handleClose).toHaveBeenCalled();
});

it('requires at least one field to be filled', async () => {
const { getByRole } = render(
<SnackbarProvider>
<ThemeProvider theme={theme}>
<GqlMockedProvider>
<EditContactAddressModal
contactId={contactId}
accountListId={accountListId}
handleClose={handleClose}
address={{
city: '',
country: '',
historic: false,
id: 'address-1',
location: '',
metroArea: '',
postalCode: '',
primaryMailingAddress: false,
region: '',
source: 'MPDX',
state: '',
street: '123 Cool Street',
createdAt: '',
startDate: '',
}}
/>
</GqlMockedProvider>
</ThemeProvider>
</SnackbarProvider>,
);

const saveButton = getByRole('button', { name: 'Save' });
await waitFor(() => expect(saveButton).not.toBeDisabled());

userEvent.clear(getByRole('combobox', { name: 'Street' }));
await waitFor(() => expect(saveButton).toBeDisabled());

userEvent.type(getByRole('textbox', { name: 'City' }), 'City');
await waitFor(() => expect(saveButton).not.toBeDisabled());
});

it('should edit contact address', async () => {
const mutationSpy = jest.fn();
const newStreet = '4321 Neat Street';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
DeleteButton,
SubmitButton,
} from 'src/components/common/Modal/ActionButtons/ActionButtons';
import { AddressUpdateInput } from 'src/graphql/types.generated';
import { useUpdateCache } from 'src/hooks/useUpdateCache';
import { isEditableSource } from 'src/utils/sourceHelper';
import Modal from '../../../../../common/Modal/Modal';
Expand All @@ -41,13 +40,13 @@ import {
import { ContactMailingFragment } from '../ContactMailing.generated';
import { useSetContactPrimaryAddressMutation } from '../SetPrimaryAddress.generated';
import { StreetAutocomplete } from '../StreetAutocomplete/StreetAutocomplete';
import { AddressSchema, addressSchema } from '../addressSchema';
import {
useDeleteContactAddressMutation,
useDonationServicesEmailQuery,
useUpdateContactAddressMutation,
} from './EditContactAddress.generated';
import { generateEmailBody } from './helpers';
import { updateAddressSchema } from './updateAddressSchema';

const ContactEditContainer = styled(Box)(({ theme }) => ({
display: 'flex',
Expand Down Expand Up @@ -95,14 +94,17 @@ export const EditContactAddressModal: React.FC<

const onSubmit = async ({
primaryMailingAddress,
street,
...attributes
}: Omit<AddressUpdateInput, 'validValues'> & {
primaryMailingAddress: boolean;
}) => {
}: AddressSchema) => {
await updateContactAddress({
variables: {
accountListId,
attributes,
attributes: {
id: address.id,
street: street ?? '',
...attributes,
},
},
});
// updateContactAddress doesn't set support setting the primaryMailingAddress field, so if
Expand Down Expand Up @@ -183,7 +185,6 @@ export const EditContactAddressModal: React.FC<
<Modal isOpen={true} title={t('Edit Address')} handleClose={handleClose}>
<Formik
initialValues={{
id: address.id,
city: address.city ?? '',
country: address.country ?? '',
historic: address.historic,
Expand All @@ -195,7 +196,7 @@ export const EditContactAddressModal: React.FC<
street: address.street ?? '',
primaryMailingAddress: address.primaryMailingAddress ?? false,
}}
validationSchema={updateAddressSchema}
validationSchema={addressSchema}
onSubmit={onSubmit}
>
{({
Expand Down Expand Up @@ -280,7 +281,6 @@ export const EditContactAddressModal: React.FC<
TextFieldProps={{
name: 'street',
label: t('Street'),
required: true,
fullWidth: true,
}}
disabled={editingDisabled}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as yup from 'yup';

export const addressSchema = yup.object({
city: yup.string().nullable(),
country: yup.string().nullable(),
historic: yup.boolean().nullable(),
location: yup.string().nullable(),
metroArea: yup.string().nullable(),
postalCode: yup.string().nullable(),
region: yup.string().nullable(),
state: yup.string().nullable(),
// Formik ignores test functions defined at the object-level, so this needs to be defined on a
// specific field. It doesn't matter which field.
street: yup
.string()
.nullable()
.test(
'one-field',
() => 'At least one address field must be filled out',
(value, { parent: address }) =>
Boolean(
address.city ||
address.country ||
address.metroArea ||
address.postalCode ||
address.region ||
address.state ||
address.street,
),
),
primaryMailingAddress: yup.boolean().nullable(false),
});

export type AddressSchema = yup.InferType<typeof addressSchema>;

0 comments on commit fd125c5

Please sign in to comment.