- {
- (address.firstName || address.lastName) &&
-
- { `${address.firstName} ` }
- { address.lastName }
-
- }
+ return !isValid ? null : (
+
+ {(address.firstName || address.lastName) && (
+
+ {`${address.firstName} `}
+ {address.lastName}
+
+ )}
- {
- (address.phone || address.company) &&
-
- { `${address.company} ` }
- { address.phone }
-
- }
+ {(address.phone || address.company) && (
+
+ {`${address.company} `}
+ {address.phone}
+
+ )}
-
-
- { `${address.address1} ` }
- {
- address.address2 &&
-
- { ` / ${address.address2 }` }
-
- }
-
+
+
+ {`${address.address1} `}
+ {address.address2 && (
+ {` / ${address.address2}`}
+ )}
+
-
- {
- address.city &&
- { `${address.city}, ` }
- }
- {
- address.localizedProvince &&
- { `${address.localizedProvince}, ` }
- }
- {
- address.postalCode &&
- { `${address.postalCode} / ` }
- }
- {
- address.localizedCountry &&
- { `${address.localizedCountry} ` }
- }
-
+
+ {address.city && {`${address.city}, `}}
+ {address.localizedProvince && (
+ {`${address.localizedProvince}, `}
+ )}
+ {address.postalCode && (
+ {`${address.postalCode} / `}
+ )}
+ {address.localizedCountry && (
+ {`${address.localizedCountry} `}
+ )}
+
+
-
;
+ );
};
export function mapToStaticAddressProps(
context: CheckoutContextProps,
- { address, type }: StaticAddressProps
+ { address, type }: StaticAddressProps,
): WithCheckoutStaticAddressProps | null {
const {
checkoutState: {
- data: {
- getBillingCountries,
- getBillingAddressFields,
- getShippingAddressFields,
- },
+ data: { getBillingCountries, getBillingAddressFields, getShippingAddressFields },
},
} = context;
return {
countries: getBillingCountries(),
- fields: type === AddressType.Billing ?
- getBillingAddressFields(address.countryCode) :
- type === AddressType.Shipping ?
- getShippingAddressFields(address.countryCode) :
- undefined,
+ fields:
+ type === AddressType.Billing
+ ? getBillingAddressFields(address.countryCode)
+ : type === AddressType.Shipping
+ ? getShippingAddressFields(address.countryCode)
+ : undefined,
};
}
diff --git a/packages/core/src/app/address/getAddressFormFieldInputId.ts b/packages/core/src/app/address/getAddressFormFieldInputId.ts
index 101e19f6bb..8f08e4ed16 100644
--- a/packages/core/src/app/address/getAddressFormFieldInputId.ts
+++ b/packages/core/src/app/address/getAddressFormFieldInputId.ts
@@ -15,6 +15,7 @@ export function getAddressFormFieldLegacyName(name: string): string {
export function getAddressFormFieldInputId(name: string): string {
return `${getAddressFormFieldLegacyName(name)}Input`;
}
+
export function getAddressFormFieldLabelId(name: string): string {
return `${getAddressFormFieldLegacyName(name)}Label`;
}
diff --git a/packages/core/src/app/address/getAddressFormFieldsValidationSchema.ts b/packages/core/src/app/address/getAddressFormFieldsValidationSchema.ts
index 51fe16baef..c77ae7d5c0 100644
--- a/packages/core/src/app/address/getAddressFormFieldsValidationSchema.ts
+++ b/packages/core/src/app/address/getAddressFormFieldsValidationSchema.ts
@@ -2,14 +2,20 @@ import { FormField, LanguageService } from '@bigcommerce/checkout-sdk';
import { memoize } from 'lodash';
import { ObjectSchema } from 'yup';
-import { getFormFieldsValidationSchema, FormFieldValues, TranslateValidationErrorFunction } from '../formFields';
+import {
+ FormFieldValues,
+ getFormFieldsValidationSchema,
+ TranslateValidationErrorFunction,
+} from '../formFields';
export interface AddressFormFieldsValidationSchemaOptions {
formFields: FormField[];
language?: LanguageService;
}
-export function getTranslateAddressError(language?: LanguageService): TranslateValidationErrorFunction {
+export function getTranslateAddressError(
+ language?: LanguageService,
+): TranslateValidationErrorFunction {
const requiredFieldErrorTranslationIds: { [fieldName: string]: string } = {
countryCode: 'address.country',
firstName: 'address.first_name',
@@ -31,10 +37,12 @@ export function getTranslateAddressError(language?: LanguageService): TranslateV
if (type === 'required') {
if (requiredFieldErrorTranslationIds[name]) {
- return language.translate(`${requiredFieldErrorTranslationIds[name]}_required_error`);
- } else {
- return language.translate(`address.custom_required_error`, { label });
+ return language.translate(
+ `${requiredFieldErrorTranslationIds[name]}_required_error`,
+ );
}
+
+ return language.translate(`address.custom_required_error`, { label });
}
if (type === 'max' && max) {
@@ -48,8 +56,6 @@ export function getTranslateAddressError(language?: LanguageService): TranslateV
if (type === 'invalid') {
return language.translate(`address.invalid_characters_error`, { label });
}
-
- return;
};
}
diff --git a/packages/core/src/app/address/googleAutocomplete/AddressSelector.spec.ts b/packages/core/src/app/address/googleAutocomplete/AddressSelector.spec.ts
index a22431eaa7..7fdcd44c52 100644
--- a/packages/core/src/app/address/googleAutocomplete/AddressSelector.spec.ts
+++ b/packages/core/src/app/address/googleAutocomplete/AddressSelector.spec.ts
@@ -1,5 +1,5 @@
-import { getGoogleAutocompletePlaceMock } from './googleAutocompleteResult.mock';
import AddressSelector from './AddressSelector';
+import { getGoogleAutocompletePlaceMock } from './googleAutocompleteResult.mock';
describe('AddressSelector', () => {
let googleAutoCompleteResponseMock: google.maps.places.PlaceResult;
@@ -11,6 +11,7 @@ describe('AddressSelector', () => {
describe('constructor', () => {
it('returns an instance of generic country accessor', () => {
const accessor = new AddressSelector(googleAutoCompleteResponseMock);
+
expect(accessor).toBeInstanceOf(AddressSelector);
});
});
@@ -18,6 +19,7 @@ describe('AddressSelector', () => {
describe('#getState()', () => {
it('returns the correct state', () => {
const accessor = new AddressSelector(googleAutoCompleteResponseMock);
+
expect(accessor.getState()).toBe('NSW');
});
});
@@ -25,6 +27,7 @@ describe('AddressSelector', () => {
describe('#getStreet()', () => {
it('returns the correct street', () => {
const accessor = new AddressSelector(googleAutoCompleteResponseMock);
+
expect(accessor.getStreet()).toBe('1-3 Smail St');
});
});
@@ -32,6 +35,7 @@ describe('AddressSelector', () => {
describe('#getStreet2()', () => {
it('returns the correct street2 value', () => {
const accessor = new AddressSelector(googleAutoCompleteResponseMock);
+
expect(accessor.getStreet2()).toBe('unit 6');
});
});
@@ -39,6 +43,7 @@ describe('AddressSelector', () => {
describe('#getCountry()', () => {
it('returns the correct country', () => {
const accessor = new AddressSelector(googleAutoCompleteResponseMock);
+
expect(accessor.getCountry()).toBe('AU');
});
});
@@ -46,6 +51,7 @@ describe('AddressSelector', () => {
describe('#getPostCode()', () => {
it('returns the correct post code', () => {
const accessor = new AddressSelector(googleAutoCompleteResponseMock);
+
expect(accessor.getPostCode()).toBe('2007');
});
});
@@ -53,13 +59,15 @@ describe('AddressSelector', () => {
describe('#getCity()', () => {
it('returns the postal town as city if present', () => {
const accessor = new AddressSelector(googleAutoCompleteResponseMock);
+
expect(accessor.getCity()).toBe('Ultimo PT (l)');
});
it('returns the locality as city if no postal town', () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const addressComponents = googleAutoCompleteResponseMock.address_components!
- .filter(address => !address.types.includes('postal_town'));
+ const addressComponents = googleAutoCompleteResponseMock.address_components!.filter(
+ (address) => !address.types.includes('postal_town'),
+ );
const accessor = new AddressSelector({
...googleAutoCompleteResponseMock,
@@ -71,8 +79,10 @@ describe('AddressSelector', () => {
it('returns the neighborhood as city if nothing else is present', () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const addressComponents = googleAutoCompleteResponseMock.address_components!
- .filter(address => !address.types.includes('postal_town') && !address.types.includes('locality'));
+ const addressComponents = googleAutoCompleteResponseMock.address_components!.filter(
+ (address) =>
+ !address.types.includes('postal_town') && !address.types.includes('locality'),
+ );
const accessor = new AddressSelector({
...googleAutoCompleteResponseMock,
diff --git a/packages/core/src/app/address/googleAutocomplete/AddressSelector.ts b/packages/core/src/app/address/googleAutocomplete/AddressSelector.ts
index be4a8fe647..76e5346590 100644
--- a/packages/core/src/app/address/googleAutocomplete/AddressSelector.ts
+++ b/packages/core/src/app/address/googleAutocomplete/AddressSelector.ts
@@ -4,9 +4,7 @@ export default class AddressSelector {
protected _address: google.maps.GeocoderAddressComponent[] | undefined;
protected _name: string;
- constructor(
- googlePlace: google.maps.places.PlaceResult
- ) {
+ constructor(googlePlace: google.maps.places.PlaceResult) {
const { address_components, name } = googlePlace;
this._name = name;
@@ -26,9 +24,11 @@ export default class AddressSelector {
}
getCity(): string {
- return this._get('postal_town', 'long_name') ||
+ return (
+ this._get('postal_town', 'long_name') ||
this._get('locality', 'long_name') ||
- this._get('neighborhood', 'short_name');
+ this._get('neighborhood', 'short_name')
+ );
}
getCountry(): string {
@@ -41,9 +41,10 @@ export default class AddressSelector {
protected _get(
type: GoogleAddressFieldType,
- access: Exclude
+ access: Exclude,
): string {
- const element = this._address && this._address.find(field => field.types.indexOf(type) !== -1);
+ const element =
+ this._address && this._address.find((field) => field.types.indexOf(type) !== -1);
if (element) {
return element[access];
diff --git a/packages/core/src/app/address/googleAutocomplete/AddressSelectorFactory.ts b/packages/core/src/app/address/googleAutocomplete/AddressSelectorFactory.ts
index ec389e4b4c..ef143725bf 100644
--- a/packages/core/src/app/address/googleAutocomplete/AddressSelectorFactory.ts
+++ b/packages/core/src/app/address/googleAutocomplete/AddressSelectorFactory.ts
@@ -6,8 +6,8 @@ export default class AddressSelectorFactory {
const addressSelector = new AddressSelector(autocompleteData);
switch (addressSelector.getCountry()) {
- case 'GB':
- return new AddressSelectorUK(autocompleteData);
+ case 'GB':
+ return new AddressSelectorUK(autocompleteData);
}
return addressSelector;
diff --git a/packages/core/src/app/address/googleAutocomplete/GoogleAutocomplete.spec.tsx b/packages/core/src/app/address/googleAutocomplete/GoogleAutocomplete.spec.tsx
index 03d69524ab..a22d123ada 100644
--- a/packages/core/src/app/address/googleAutocomplete/GoogleAutocomplete.spec.tsx
+++ b/packages/core/src/app/address/googleAutocomplete/GoogleAutocomplete.spec.tsx
@@ -9,7 +9,13 @@ describe('GoogleAutocomplete Component', () => {
// At the moment, jest.mock('...') doesn't seem to do the trick.
it('renders input with initial value', () => {
- const tree = render();
+ const tree = render(
+ ,
+ );
expect(toJson(tree)).toMatchSnapshot();
});
diff --git a/packages/core/src/app/address/googleAutocomplete/GoogleAutocomplete.tsx b/packages/core/src/app/address/googleAutocomplete/GoogleAutocomplete.tsx
index 677e5776c5..319ead59b7 100644
--- a/packages/core/src/app/address/googleAutocomplete/GoogleAutocomplete.tsx
+++ b/packages/core/src/app/address/googleAutocomplete/GoogleAutocomplete.tsx
@@ -39,62 +39,51 @@ class GoogleAutocomplete extends PureComponent
);
}
- private onSelect: (item: AutocompleteItem) => void = item => {
- const {
- fields,
- onSelect = noop,
- nextElement,
- } = this.props;
-
- this.googleAutocompleteService.getPlacesServices().then(service => {
- service.getDetails({
- placeId: item.id,
- fields: fields || ['address_components', 'name'],
- }, result => {
- if (nextElement) {
- nextElement.focus();
- }
-
- onSelect(result, item);
- });
+ private onSelect: (item: AutocompleteItem) => void = (item) => {
+ const { fields, onSelect = noop, nextElement } = this.props;
+
+ this.googleAutocompleteService.getPlacesServices().then((service) => {
+ service.getDetails(
+ {
+ placeId: item.id,
+ fields: fields || ['address_components', 'name'],
+ },
+ (result) => {
+ if (nextElement) {
+ nextElement.focus();
+ }
+
+ onSelect(result, item);
+ },
+ );
});
};
- private onChange: (input: string) => void = input => {
- const {
- isAutocompleteEnabled,
- onChange = noop,
- } = this.props;
+ private onChange: (input: string) => void = (input) => {
+ const { isAutocompleteEnabled, onChange = noop } = this.props;
onChange(input, false);
@@ -113,18 +102,16 @@ class GoogleAutocomplete extends PureComponent {
- service.getPlacePredictions({
- input,
- types: types || ['geocode'],
- componentRestrictions,
- }, results =>
- this.setState({ items: this.toAutocompleteItems(results) })
+ const { componentRestrictions, types } = this.props;
+
+ this.googleAutocompleteService.getAutocompleteService().then((service) => {
+ service.getPlacePredictions(
+ {
+ input,
+ types: types || ['geocode'],
+ componentRestrictions,
+ },
+ (results) => this.setState({ items: this.toAutocompleteItems(results) }),
);
});
}
@@ -143,8 +130,10 @@ class GoogleAutocomplete extends PureComponent ({
+ private toAutocompleteItems(
+ results?: google.maps.places.AutocompletePrediction[],
+ ): AutocompleteItem[] {
+ return (results || []).map((result) => ({
label: result.description,
value: result.structured_formatting.main_text,
highlightedSlices: result.matched_substrings,
diff --git a/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteFormField.tsx b/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteFormField.tsx
index f71b5cb4db..cb1f7208ae 100644
--- a/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteFormField.tsx
+++ b/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteFormField.tsx
@@ -1,11 +1,14 @@
import { FormField as FormFieldType } from '@bigcommerce/checkout-sdk';
import { FieldProps } from 'formik';
-import React, { memo, useCallback, useMemo, FunctionComponent } from 'react';
+import React, { FunctionComponent, memo, useCallback, useMemo } from 'react';
import { TranslatedString } from '../../locale';
import { AutocompleteItem } from '../../ui/autocomplete';
import { FormField, Label } from '../../ui/form';
-import { getAddressFormFieldInputId, getAddressFormFieldLabelId } from '../getAddressFormFieldInputId';
+import {
+ getAddressFormFieldInputId,
+ getAddressFormFieldLabelId,
+} from '../getAddressFormFieldInputId';
import GoogleAutocomplete from './GoogleAutocomplete';
@@ -21,11 +24,8 @@ export interface GoogleAutocompleteFormFieldProps {
onChange(value: string, isOpen: boolean): void;
}
-const GoogleAutocompleteFormField: FunctionComponent = ({
- field: {
- default: placeholder,
- name,
- },
+const GoogleAutocompleteFormField: FunctionComponent = ({
+ field: { default: placeholder, name },
countryCode,
supportedCountries,
parentFieldName,
@@ -37,52 +37,58 @@ const GoogleAutocompleteFormField: FunctionComponent {
const fieldName = parentFieldName ? `${parentFieldName}.${name}` : name;
- const labelContent = useMemo(() => (
-
- ), []);
+ const labelContent = useMemo(() => , []);
const labelId = getAddressFormFieldLabelId(name);
- const inputProps = useMemo(() => ({
- className: 'form-input optimizedCheckout-form-input',
- id: getAddressFormFieldInputId(name),
- 'aria-labelledby': labelId,
- placeholder,
- }), [name, labelId, placeholder]);
+ const inputProps = useMemo(
+ () => ({
+ className: 'form-input optimizedCheckout-form-input',
+ id: getAddressFormFieldInputId(name),
+ 'aria-labelledby': labelId,
+ placeholder,
+ }),
+ [name, labelId, placeholder],
+ );
- const renderInput = useCallback(({ field }: FieldProps) => (
- -1 :
- false }
- nextElement={ nextElement }
- onChange={ onChange }
- onSelect={ onSelect }
- onToggleOpen={ onToggleOpen }
- />
- ), [
- apiKey,
- countryCode,
- inputProps,
- nextElement,
- onChange,
- onSelect,
- onToggleOpen,
- supportedCountries,
- ]);
+ const renderInput = useCallback(
+ ({ field }: FieldProps) => (
+ -1 : false
+ }
+ nextElement={nextElement}
+ onChange={onChange}
+ onSelect={onSelect}
+ onToggleOpen={onToggleOpen}
+ />
+ ),
+ [
+ apiKey,
+ countryCode,
+ inputProps,
+ nextElement,
+ onChange,
+ onSelect,
+ onToggleOpen,
+ supportedCountries,
+ ],
+ );
return (
-
+
{ labelContent } }
- name={ fieldName }
+ input={renderInput}
+ label={
+
+ }
+ name={fieldName}
/>
);
diff --git a/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteScriptLoader.ts b/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteScriptLoader.ts
index e3c16eb9e3..cb9ef9aeb2 100644
--- a/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteScriptLoader.ts
+++ b/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteScriptLoader.ts
@@ -32,8 +32,9 @@ export default class GoogleAutocompleteScriptLoader {
reject();
};
- this._scriptLoader.loadScript(`//maps.googleapis.com/maps/api/js?${params}`)
- .catch(e => {
+ this._scriptLoader
+ .loadScript(`//maps.googleapis.com/maps/api/js?${params}`)
+ .catch((e) => {
this._googleAutoComplete = undefined;
throw e;
});
@@ -46,9 +47,11 @@ export default class GoogleAutocompleteScriptLoader {
function isAutocompleteWindow(window: Window): window is GoogleAutocompleteWindow {
const autocompleteWindow = window as GoogleAutocompleteWindow;
- return Boolean(autocompleteWindow.google &&
- autocompleteWindow.google.maps &&
- autocompleteWindow.google.maps.places);
+ return Boolean(
+ autocompleteWindow.google &&
+ autocompleteWindow.google.maps &&
+ autocompleteWindow.google.maps.places,
+ );
}
export interface GoogleCallbackWindow extends Window {
diff --git a/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteService.ts b/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteService.ts
index 14f3806a5a..d8de9a2afb 100644
--- a/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteService.ts
+++ b/packages/core/src/app/address/googleAutocomplete/GoogleAutocompleteService.ts
@@ -7,13 +7,14 @@ export default class GoogleAutocompleteService {
constructor(
private _apiKey: string,
- private _scriptLoader: GoogleAutocompleteScriptLoader = getGoogleAutocompleteScriptLoader()
+ private _scriptLoader: GoogleAutocompleteScriptLoader = getGoogleAutocompleteScriptLoader(),
) {}
getAutocompleteService(): Promise
{
if (!this._autocompletePromise) {
- this._autocompletePromise = this._scriptLoader.loadMapsSdk(this._apiKey)
- .then(googleMapsSdk => {
+ this._autocompletePromise = this._scriptLoader
+ .loadMapsSdk(this._apiKey)
+ .then((googleMapsSdk) => {
if (!googleMapsSdk.places.AutocompleteService) {
throw new Error('`AutocompleteService` is undefined');
}
@@ -29,8 +30,9 @@ export default class GoogleAutocompleteService {
const node = document.createElement('div');
if (!this._placesPromise) {
- this._placesPromise = this._scriptLoader.loadMapsSdk(this._apiKey)
- .then(googleMapsSdk => {
+ this._placesPromise = this._scriptLoader
+ .loadMapsSdk(this._apiKey)
+ .then((googleMapsSdk) => {
if (!googleMapsSdk.places.PlacesService) {
throw new Error('`PlacesService` is undefined');
}
diff --git a/packages/core/src/app/address/googleAutocomplete/getGoogleAutocompleteScriptLoader.spec.ts b/packages/core/src/app/address/googleAutocomplete/getGoogleAutocompleteScriptLoader.spec.ts
index d34933d3a5..21fb0655fa 100644
--- a/packages/core/src/app/address/googleAutocomplete/getGoogleAutocompleteScriptLoader.spec.ts
+++ b/packages/core/src/app/address/googleAutocomplete/getGoogleAutocompleteScriptLoader.spec.ts
@@ -1,7 +1,9 @@
import { getScriptLoader, ScriptLoader } from '@bigcommerce/script-loader';
+import GoogleAutocompleteScriptLoader, {
+ GoogleCallbackWindow,
+} from './GoogleAutocompleteScriptLoader';
import { GoogleAutocompleteWindow } from './googleAutocompleteTypes';
-import GoogleAutocompleteScriptLoader, { GoogleCallbackWindow } from './GoogleAutocompleteScriptLoader';
describe('GoogleAutocompleteScriptLoader', () => {
const scriptLoader: ScriptLoader = getScriptLoader();
@@ -33,13 +35,14 @@ describe('GoogleAutocompleteScriptLoader', () => {
});
it('calls loadScript with the right parameters', () => {
- expect(scriptLoader.loadScript)
- .toHaveBeenCalledWith([
+ expect(scriptLoader.loadScript).toHaveBeenCalledWith(
+ [
'//maps.googleapis.com/maps/api/js?language=en',
'key=foo',
'libraries=places',
'callback=initAutoComplete',
- ].join('&'));
+ ].join('&'),
+ );
});
it('calls loadScript once', async () => {
@@ -47,8 +50,7 @@ describe('GoogleAutocompleteScriptLoader', () => {
await googleScriptLoader.loadMapsSdk('y');
await googleScriptLoader.loadMapsSdk('z');
- expect(scriptLoader.loadScript)
- .toHaveBeenCalledTimes(1);
+ expect(scriptLoader.loadScript).toHaveBeenCalledTimes(1);
});
});
});
diff --git a/packages/core/src/app/address/googleAutocomplete/googleAutocompleteResult.mock.ts b/packages/core/src/app/address/googleAutocomplete/googleAutocompleteResult.mock.ts
index 8e3e2bd219..b02135b622 100644
--- a/packages/core/src/app/address/googleAutocomplete/googleAutocompleteResult.mock.ts
+++ b/packages/core/src/app/address/googleAutocomplete/googleAutocompleteResult.mock.ts
@@ -5,76 +5,52 @@ export function getGoogleAutocompletePlaceMock(): google.maps.places.PlaceResult
{
long_name: 'unit 6',
short_name: 'unit 6',
- types: [
- 'subpremise',
- ],
+ types: ['subpremise'],
},
{
long_name: '1-3 (l)',
short_name: '1-3 (s)',
- types: [
- 'street_number',
- ],
+ types: ['street_number'],
},
{
long_name: 'Smail Street',
short_name: 'Smail St',
- types: [
- 'route',
- ],
+ types: ['route'],
},
{
long_name: 'Ultimo PT (l)',
short_name: 'Ultimo PT',
- types: [
- 'postal_town',
- ],
+ types: ['postal_town'],
},
{
long_name: 'Ultimo (l)',
short_name: 'Ultimo',
- types: [
- 'locality',
- 'political',
- ],
+ types: ['locality', 'political'],
},
{
long_name: 'Ultimo N (l)',
short_name: 'Ultimo N',
- types: [
- 'neighborhood',
- ],
+ types: ['neighborhood'],
},
{
long_name: 'Council of the City of Sydney',
short_name: 'Sydney',
- types: [
- 'administrative_area_level_2',
- 'political',
- ],
+ types: ['administrative_area_level_2', 'political'],
},
{
long_name: 'New South Wales',
short_name: 'NSW',
- types: [
- 'administrative_area_level_1',
- 'political',
- ],
+ types: ['administrative_area_level_1', 'political'],
},
{
long_name: 'Australia',
short_name: 'AU',
- types: [
- 'country',
- 'political',
- ],
+ types: ['country', 'political'],
},
{
long_name: '2007 (l)',
short_name: '2007',
- types: [
- 'postal_code',
- ],
+ types: ['postal_code'],
},
],
} as google.maps.places.PlaceResult;
diff --git a/packages/core/src/app/address/googleAutocomplete/googleAutocompleteTypes.ts b/packages/core/src/app/address/googleAutocomplete/googleAutocompleteTypes.ts
index 77f66668f5..3b408eff69 100644
--- a/packages/core/src/app/address/googleAutocomplete/googleAutocompleteTypes.ts
+++ b/packages/core/src/app/address/googleAutocomplete/googleAutocompleteTypes.ts
@@ -1,28 +1,28 @@
-export type GoogleAutocompleteOptionTypes = 'establishment' | 'geocode' | 'address';
+export type GoogleAutocompleteOptionTypes = 'establishment' | 'geocode' | 'address';
export type GoogleAutocompleteFields =
- 'address_components' |
- 'adr_address' |
- 'aspects' |
- 'formatted_address' |
- 'formatted_phone_number' |
- 'geometry' |
- 'html_attributions' |
- 'icon' |
- 'international_phone_number' |
- 'name' |
- 'opening_hours' |
- 'photos' |
- 'place_id' |
- 'plus_code' |
- 'price_level' |
- 'rating' |
- 'reviews' |
- 'types' |
- 'url' |
- 'utc_offset' |
- 'vicinity' |
- 'website';
+ | 'address_components'
+ | 'adr_address'
+ | 'aspects'
+ | 'formatted_address'
+ | 'formatted_phone_number'
+ | 'geometry'
+ | 'html_attributions'
+ | 'icon'
+ | 'international_phone_number'
+ | 'name'
+ | 'opening_hours'
+ | 'photos'
+ | 'place_id'
+ | 'plus_code'
+ | 'price_level'
+ | 'rating'
+ | 'reviews'
+ | 'types'
+ | 'url'
+ | 'utc_offset'
+ | 'vicinity'
+ | 'website';
export type GoogleAutocompleteEvent = 'place_changed';
@@ -40,14 +40,14 @@ export interface GoogleAutocompleteWindow extends Window {
}
export type GoogleAddressFieldType =
- 'postal_town' |
- 'administrative_area_level_1' |
- 'administrative_area_level_2' |
- 'locality' |
- 'neighborhood' |
- 'postal_code' |
- 'street_number' |
- 'route' |
- 'political' |
- 'country' |
- 'subpremise';
+ | 'postal_town'
+ | 'administrative_area_level_1'
+ | 'administrative_area_level_2'
+ | 'locality'
+ | 'neighborhood'
+ | 'postal_code'
+ | 'street_number'
+ | 'route'
+ | 'political'
+ | 'country'
+ | 'subpremise';
diff --git a/packages/core/src/app/address/googleAutocomplete/mapToAddress.ts b/packages/core/src/app/address/googleAutocomplete/mapToAddress.ts
index 727dd987ea..07c5109991 100644
--- a/packages/core/src/app/address/googleAutocomplete/mapToAddress.ts
+++ b/packages/core/src/app/address/googleAutocomplete/mapToAddress.ts
@@ -4,7 +4,7 @@ import AddressSelectorFactory from './AddressSelectorFactory';
export default function mapToAddress(
autocompleteData: google.maps.places.PlaceResult,
- countries: Country[] = []
+ countries: Country[] = [],
): Partial {
if (!autocompleteData || !autocompleteData.address_components) {
return {};
@@ -13,7 +13,7 @@ export default function mapToAddress(
const accessor = AddressSelectorFactory.create(autocompleteData);
const state = accessor.getState();
const countryCode = accessor.getCountry();
- const country = countries && countries.find(c => countryCode === c.code);
+ const country = countries && countries.find((c) => countryCode === c.code);
const street2 = accessor.getStreet2();
return {
@@ -21,17 +21,12 @@ export default function mapToAddress(
city: accessor.getCity(),
countryCode,
postalCode: accessor.getPostCode(),
- ...state ? getState(state, country && country.subdivisions) : {},
+ ...(state ? getState(state, country && country.subdivisions) : {}),
};
}
-function getState(
- stateName: string,
- states: Region[] = []
-): Partial {
- const state = states.find(({ code, name }: Region) =>
- code === stateName || name === stateName
- );
+function getState(stateName: string, states: Region[] = []): Partial {
+ const state = states.find(({ code, name }: Region) => code === stateName || name === stateName);
if (!state) {
return {
diff --git a/packages/core/src/app/address/index.ts b/packages/core/src/app/address/index.ts
index a52337414e..30b0d60a5b 100644
--- a/packages/core/src/app/address/index.ts
+++ b/packages/core/src/app/address/index.ts
@@ -12,4 +12,4 @@ export { default as isEqualAddress } from './isEqualAddress';
export {
default as getAddressFormFieldsValidationSchema,
getTranslateAddressError,
- } from './getAddressFormFieldsValidationSchema';
+} from './getAddressFormFieldsValidationSchema';
diff --git a/packages/core/src/app/address/isEqualAddress.spec.ts b/packages/core/src/app/address/isEqualAddress.spec.ts
index 6c908c599e..22d9ca0f4f 100644
--- a/packages/core/src/app/address/isEqualAddress.spec.ts
+++ b/packages/core/src/app/address/isEqualAddress.spec.ts
@@ -6,84 +6,113 @@ import mapAddressToFormValues from './mapAddressToFormValues';
describe('isEqualAddress', () => {
it('returns true when ignored values are different', () => {
- expect(isEqualAddress(getAddress(), {
- ...getAddress(),
- stateOrProvinceCode: 'w',
- country: 'none',
- id: 'x',
- email: 'y',
- shouldSaveAddress: false,
- type: 'z',
- })).toBeTruthy();
+ expect(
+ isEqualAddress(getAddress(), {
+ ...getAddress(),
+ stateOrProvinceCode: 'w',
+ country: 'none',
+ id: 'x',
+ email: 'y',
+ shouldSaveAddress: false,
+ type: 'z',
+ }),
+ ).toBeTruthy();
});
it('returns true when stateOrProvinceCode matches stateOrProvince', () => {
- expect(isEqualAddress({
- ...getAddress(),
- stateOrProvince: '',
- stateOrProvinceCode: 'CA',
- }, {
- ...getAddress(),
- stateOrProvince: 'California',
- stateOrProvinceCode: 'CA',
- })).toBeTruthy();
+ expect(
+ isEqualAddress(
+ {
+ ...getAddress(),
+ stateOrProvince: '',
+ stateOrProvinceCode: 'CA',
+ },
+ {
+ ...getAddress(),
+ stateOrProvince: 'California',
+ stateOrProvinceCode: 'CA',
+ },
+ ),
+ ).toBeTruthy();
- expect(isEqualAddress({
- ...getAddress(),
- stateOrProvince: 'California',
- stateOrProvinceCode: '',
- }, {
- ...getAddress(),
- stateOrProvince: 'California',
- stateOrProvinceCode: 'CA',
- })).toBeTruthy();
+ expect(
+ isEqualAddress(
+ {
+ ...getAddress(),
+ stateOrProvince: 'California',
+ stateOrProvinceCode: '',
+ },
+ {
+ ...getAddress(),
+ stateOrProvince: 'California',
+ stateOrProvinceCode: 'CA',
+ },
+ ),
+ ).toBeTruthy();
- expect(isEqualAddress({
- ...getAddress(),
- stateOrProvince: '',
- stateOrProvinceCode: '',
- }, {
- ...getAddress(),
- stateOrProvince: '',
- stateOrProvinceCode: '',
- })).toBeTruthy();
+ expect(
+ isEqualAddress(
+ {
+ ...getAddress(),
+ stateOrProvince: '',
+ stateOrProvinceCode: '',
+ },
+ {
+ ...getAddress(),
+ stateOrProvince: '',
+ stateOrProvinceCode: '',
+ },
+ ),
+ ).toBeTruthy();
});
it('returns false when values are different', () => {
- expect(isEqualAddress({
- ...getAddress(),
- stateOrProvince: 'California',
- stateOrProvinceCode: '',
- }, {
- ...getAddress(),
- stateOrProvince: 'New York',
- stateOrProvinceCode: '',
- })).toBeFalsy();
+ expect(
+ isEqualAddress(
+ {
+ ...getAddress(),
+ stateOrProvince: 'California',
+ stateOrProvinceCode: '',
+ },
+ {
+ ...getAddress(),
+ stateOrProvince: 'New York',
+ stateOrProvinceCode: '',
+ },
+ ),
+ ).toBeFalsy();
- expect(isEqualAddress({
- ...getAddress(),
- stateOrProvince: '',
- stateOrProvinceCode: 'CA',
- }, {
- ...getAddress(),
- stateOrProvince: '',
- stateOrProvinceCode: 'NY',
- })).toBeFalsy();
+ expect(
+ isEqualAddress(
+ {
+ ...getAddress(),
+ stateOrProvince: '',
+ stateOrProvinceCode: 'CA',
+ },
+ {
+ ...getAddress(),
+ stateOrProvince: '',
+ stateOrProvinceCode: 'NY',
+ },
+ ),
+ ).toBeFalsy();
});
it('returns true for transformed address', () => {
const address = getAddress();
const transformedAddress = mapAddressFromFormValues(
- mapAddressToFormValues(getAddressFormFields(), address)
+ mapAddressToFormValues(getAddressFormFields(), address),
);
expect(isEqualAddress(address, transformedAddress)).toBeTruthy();
});
it('returns true when when custom fields are empty', () => {
- expect(isEqualAddress(getAddress(), {
- ...getAddress(),
- customFields: [{ fieldId: 'foo', fieldValue: '' }],
- })).toBeTruthy();
+ expect(
+ isEqualAddress(getAddress(), {
+ ...getAddress(),
+ customFields: [{ fieldId: 'foo', fieldValue: '' }],
+ }),
+ ).toBeTruthy();
});
});
diff --git a/packages/core/src/app/address/isEqualAddress.ts b/packages/core/src/app/address/isEqualAddress.ts
index 53e90826e7..2390a3b353 100644
--- a/packages/core/src/app/address/isEqualAddress.ts
+++ b/packages/core/src/app/address/isEqualAddress.ts
@@ -1,18 +1,26 @@
-import { Address, AddressRequestBody, BillingAddress, CustomerAddress } from '@bigcommerce/checkout-sdk';
+import {
+ Address,
+ AddressRequestBody,
+ BillingAddress,
+ CustomerAddress,
+} from '@bigcommerce/checkout-sdk';
import { isEqual, omit } from 'lodash';
type ComparableAddress = CustomerAddress | Address | BillingAddress | AddressRequestBody;
type ComparableAddressFields = keyof CustomerAddress | keyof Address | keyof BillingAddress;
-export default function isEqualAddress(address1?: ComparableAddress, address2?: ComparableAddress): boolean {
+export default function isEqualAddress(
+ address1?: ComparableAddress,
+ address2?: ComparableAddress,
+): boolean {
if (!address1 || !address2) {
return false;
}
- return isEqual(
- normalizeAddress(address1),
- normalizeAddress(address2)
- ) && isSameState(address1, address2);
+ return (
+ isEqual(normalizeAddress(address1), normalizeAddress(address2)) &&
+ isSameState(address1, address2)
+ );
}
function isSameState(address1: ComparableAddress, address2: ComparableAddress): boolean {
@@ -20,12 +28,17 @@ function isSameState(address1: ComparableAddress, address2: ComparableAddress):
return true;
}
- if (address1.stateOrProvinceCode && address1.stateOrProvinceCode === address2.stateOrProvinceCode) {
+ if (
+ address1.stateOrProvinceCode &&
+ address1.stateOrProvinceCode === address2.stateOrProvinceCode
+ ) {
return true;
}
- return address1.stateOrProvince === address2.stateOrProvince &&
- address1.stateOrProvinceCode === address2.stateOrProvinceCode;
+ return (
+ address1.stateOrProvince === address2.stateOrProvince &&
+ address1.stateOrProvinceCode === address2.stateOrProvinceCode
+ );
}
function normalizeAddress(address: ComparableAddress) {
@@ -44,6 +57,6 @@ function normalizeAddress(address: ComparableAddress) {
...address,
customFields: (address.customFields || []).filter(({ fieldValue }) => !!fieldValue),
},
- ignoredFields
+ ignoredFields,
);
}
diff --git a/packages/core/src/app/address/isValidAddress.spec.ts b/packages/core/src/app/address/isValidAddress.spec.ts
index 864686d540..21a2c42e0b 100644
--- a/packages/core/src/app/address/isValidAddress.spec.ts
+++ b/packages/core/src/app/address/isValidAddress.spec.ts
@@ -4,47 +4,37 @@ import isValidAddress from './isValidAddress';
describe('isValidAddress()', () => {
it('returns true if all required fields are defined', () => {
- expect(isValidAddress(getAddress(), getFormFields()))
- .toEqual(true);
+ expect(isValidAddress(getAddress(), getFormFields())).toBe(true);
});
it('returns false if some required fields are not defined', () => {
- expect(isValidAddress({ ...getAddress(), address1: '' }, getFormFields()))
- .toEqual(false);
+ expect(isValidAddress({ ...getAddress(), address1: '' }, getFormFields())).toBe(false);
});
describe('when field is dropdown', () => {
it('returns false if dropdown is required but not defined', () => {
const output = isValidAddress(
getAddress(),
- getFormFields().map(field => (
- field.fieldType === 'dropdown' ?
- { ...field, required: true } :
- field
- ))
+ getFormFields().map((field) =>
+ field.fieldType === 'dropdown' ? { ...field, required: true } : field,
+ ),
);
- expect(output)
- .toEqual(false);
+ expect(output).toBe(false);
});
it('returns true if dropdown is required and defined', () => {
const output = isValidAddress(
{
...getAddress(),
- customFields: [
- { fieldId: 'field_27', fieldValue: '0' },
- ],
+ customFields: [{ fieldId: 'field_27', fieldValue: '0' }],
},
- getFormFields().map(field => (
- field.type === 'array' ?
- { ...field, required: true } :
- field
- ))
+ getFormFields().map((field) =>
+ field.type === 'array' ? { ...field, required: true } : field,
+ ),
);
- expect(output)
- .toEqual(true);
+ expect(output).toBe(true);
});
});
@@ -53,33 +43,27 @@ describe('isValidAddress()', () => {
const output = isValidAddress(
{
...getAddress(),
- customFields: [
- { fieldId: 'field_31', fieldValue: 0 },
- ],
+ customFields: [{ fieldId: 'field_31', fieldValue: 0 }],
},
- getFormFields().map(field => (
- field.type === 'integer' ?
- { ...field, required: true } :
- field
- ))
+ getFormFields().map((field) =>
+ field.type === 'integer' ? { ...field, required: true } : field,
+ ),
);
- expect(output)
- .toEqual(true);
+ expect(output).toBe(true);
});
it('returns false if field is required and not defined', () => {
const output = isValidAddress(
getAddress(),
- getFormFields().map(field => (
- (typeof field.type !== undefined && field.type === 'integer') ?
- { ...field, required: true } :
- field
- ))
+ getFormFields().map((field) =>
+ typeof field.type !== undefined && field.type === 'integer'
+ ? { ...field, required: true }
+ : field,
+ ),
);
- expect(output)
- .toEqual(false);
+ expect(output).toBe(false);
});
});
});
diff --git a/packages/core/src/app/address/isValidCustomerAddress.ts b/packages/core/src/app/address/isValidCustomerAddress.ts
index d8ba9a7a30..1bff236851 100644
--- a/packages/core/src/app/address/isValidCustomerAddress.ts
+++ b/packages/core/src/app/address/isValidCustomerAddress.ts
@@ -7,11 +7,11 @@ import isValidAddress from './isValidAddress';
export default function isValidCustomerAddress(
address: Address | undefined,
addresses: CustomerAddress[],
- formFields: FormField[]
+ formFields: FormField[],
): boolean {
if (!address || !isValidAddress(address, formFields)) {
return false;
}
- return some(addresses, customerAddress => isEqualAddress(customerAddress, address));
+ return some(addresses, (customerAddress) => isEqualAddress(customerAddress, address));
}
diff --git a/packages/core/src/app/address/localizeAddress.spec.ts b/packages/core/src/app/address/localizeAddress.spec.ts
index 7327f75681..92c32b2971 100644
--- a/packages/core/src/app/address/localizeAddress.spec.ts
+++ b/packages/core/src/app/address/localizeAddress.spec.ts
@@ -29,7 +29,7 @@ describe('localizeAddress', () => {
});
it('keeps same value if unable to provinceCode', () => {
- const countries = getCountries().map(country => ({
+ const countries = getCountries().map((country) => ({
...country,
subdivisions: [],
}));
diff --git a/packages/core/src/app/address/localizeAddress.ts b/packages/core/src/app/address/localizeAddress.ts
index 44724f984d..4a3aefaae3 100644
--- a/packages/core/src/app/address/localizeAddress.ts
+++ b/packages/core/src/app/address/localizeAddress.ts
@@ -5,11 +5,11 @@ import { LocalizedGeography } from '../geography';
const localizeAddress = (
address: T1,
- countries?: Country[]
+ countries?: Country[],
): T1 & LocalizedGeography => {
- const country = find(countries, { code: address.countryCode });
+ const country = find(countries, { code: address.countryCode });
const states = !country || isEmpty(country.subdivisions) ? [] : country.subdivisions;
- const state = find(states, { code: address.stateOrProvinceCode });
+ const state = find(states, { code: address.stateOrProvinceCode });
return {
...address,
diff --git a/packages/core/src/app/address/mapAddressFromFormValues.spec.ts b/packages/core/src/app/address/mapAddressFromFormValues.spec.ts
index 6f55ea05e6..e928dcba21 100644
--- a/packages/core/src/app/address/mapAddressFromFormValues.spec.ts
+++ b/packages/core/src/app/address/mapAddressFromFormValues.spec.ts
@@ -12,8 +12,7 @@ describe('mapAddressFromFormValues', () => {
customFields: {},
};
- expect(mapAddressFromFormValues(formValues))
- .toMatchObject(getShippingAddress());
+ expect(mapAddressFromFormValues(formValues)).toMatchObject(getShippingAddress());
});
it('converts formats date values to YYYY-MM-DD format', () => {
diff --git a/packages/core/src/app/address/mapAddressToFormValues.ts b/packages/core/src/app/address/mapAddressToFormValues.ts
index afeeaf32f1..99955b6a1b 100644
--- a/packages/core/src/app/address/mapAddressToFormValues.ts
+++ b/packages/core/src/app/address/mapAddressToFormValues.ts
@@ -6,8 +6,11 @@ export type AddressFormValues = Pick {
if (custom) {
@@ -15,13 +18,18 @@ export default function mapAddressToFormValues(fields: FormField[], address?: Ad
addressFormValues.customFields = {};
}
- const field = address &&
+ const field =
+ address &&
address.customFields &&
address.customFields.find(({ fieldId }) => fieldId === name);
- const fieldValue = (field && field.fieldValue);
+ const fieldValue = field && field.fieldValue;
- addressFormValues.customFields[name] = getValue(fieldType, fieldValue, defaultValue);
+ addressFormValues.customFields[name] = getValue(
+ fieldType,
+ fieldValue,
+ defaultValue,
+ );
return addressFormValues;
}
@@ -32,13 +40,12 @@ export default function mapAddressToFormValues(fields: FormField[], address?: Ad
return addressFormValues;
},
- {} as AddressFormValues
+ {} as AddressFormValues,
),
- });
+ };
- values.shouldSaveAddress = address && address.shouldSaveAddress !== undefined ?
- address.shouldSaveAddress :
- true;
+ values.shouldSaveAddress =
+ address && address.shouldSaveAddress !== undefined ? address.shouldSaveAddress : true;
// Manually backfill stateOrProvince to avoid Formik warning (uncontrolled to controlled input)
if (values.stateOrProvince === undefined) {
@@ -52,7 +59,11 @@ export default function mapAddressToFormValues(fields: FormField[], address?: Ad
return values;
}
-function getValue(fieldType?: string, fieldValue?: string | string[] | number, defaultValue?: string): string | string[] | number | Date | undefined {
+function getValue(
+ fieldType?: string,
+ fieldValue?: string | string[] | number,
+ defaultValue?: string,
+): string | string[] | number | Date | undefined {
if (fieldValue === undefined || fieldValue === null) {
return getDefaultValue(fieldType, defaultValue);
}
@@ -76,6 +87,8 @@ function getDefaultValue(fieldType?: string, defaultValue?: string): string | st
return defaultValue || '';
}
-function isSystemAddressFieldName(fieldName: string): fieldName is Exclude {
+function isSystemAddressFieldName(
+ fieldName: string,
+): fieldName is Exclude {
return fieldName !== 'customFields' && fieldName !== 'shouldSaveAddress';
}
diff --git a/packages/core/src/app/auto-loader.ts b/packages/core/src/app/auto-loader.ts
index 2f4ecaee34..1e04a321f7 100644
--- a/packages/core/src/app/auto-loader.ts
+++ b/packages/core/src/app/auto-loader.ts
@@ -23,16 +23,9 @@ function isCustomCheckoutWindow(window: Window): window is CustomCheckoutWindow
throw new Error('Checkout config is missing.');
}
- const {
- renderOrderConfirmation,
- renderCheckout,
- } = await loadFiles();
-
- const {
- orderId,
- checkoutId,
- ...appProps
- } = window.checkoutConfig;
+ const { renderOrderConfirmation, renderCheckout } = await loadFiles();
+
+ const { orderId, checkoutId, ...appProps } = window.checkoutConfig;
if (orderId) {
renderOrderConfirmation({ ...appProps, orderId });
diff --git a/packages/core/src/app/billing/Billing.spec.tsx b/packages/core/src/app/billing/Billing.spec.tsx
index f550682f4e..caf948c92f 100644
--- a/packages/core/src/app/billing/Billing.spec.tsx
+++ b/packages/core/src/app/billing/Billing.spec.tsx
@@ -1,4 +1,9 @@
-import { createCheckoutService, CheckoutSelectors, CheckoutService, LineItemMap } from '@bigcommerce/checkout-sdk';
+import {
+ CheckoutSelectors,
+ CheckoutService,
+ createCheckoutService,
+ LineItemMap,
+} from '@bigcommerce/checkout-sdk';
import { mount, ReactWrapper } from 'enzyme';
import React, { FunctionComponent } from 'react';
@@ -12,8 +17,8 @@ import { getCountries } from '../geography/countries.mock';
import { createLocaleContext, LocaleContext, LocaleContextType } from '../locale';
import { OrderComments } from '../orderComments';
-import { getBillingAddress } from './billingAddresses.mock';
import Billing, { BillingProps } from './Billing';
+import { getBillingAddress } from './billingAddresses.mock';
import BillingForm from './BillingForm';
describe('Billing Component', () => {
@@ -36,47 +41,51 @@ describe('Billing Component', () => {
onUnhandledError: jest.fn(),
};
- jest.spyOn(checkoutService.getState().data, 'getBillingAddressFields')
- .mockReturnValue(getFormFields());
+ jest.spyOn(checkoutService.getState().data, 'getBillingAddressFields').mockReturnValue(
+ getFormFields(),
+ );
- jest.spyOn(checkoutService.getState().data, 'getConfig')
- .mockReturnValue(getStoreConfig());
+ jest.spyOn(checkoutService.getState().data, 'getConfig').mockReturnValue(getStoreConfig());
- jest.spyOn(checkoutService.getState().data, 'getCart')
- .mockReturnValue(getCart());
+ jest.spyOn(checkoutService.getState().data, 'getCart').mockReturnValue(getCart());
- jest.spyOn(checkoutService.getState().data, 'getCheckout')
- .mockReturnValue(getCheckout());
+ jest.spyOn(checkoutService.getState().data, 'getCheckout').mockReturnValue(getCheckout());
- jest.spyOn(checkoutService.getState().data, 'getCustomer')
- .mockReturnValue(getCustomer());
+ jest.spyOn(checkoutService.getState().data, 'getCustomer').mockReturnValue(getCustomer());
- jest.spyOn(checkoutService.getState().data, 'getBillingCountries')
- .mockReturnValue(getCountries());
+ jest.spyOn(checkoutService.getState().data, 'getBillingCountries').mockReturnValue(
+ getCountries(),
+ );
- jest.spyOn(checkoutService.getState().statuses, 'isUpdatingBillingAddress')
- .mockReturnValue(false);
+ jest.spyOn(checkoutService.getState().statuses, 'isUpdatingBillingAddress').mockReturnValue(
+ false,
+ );
- jest.spyOn(checkoutService.getState().data, 'getBillingAddress')
- .mockReturnValue(billingAddress);
+ jest.spyOn(checkoutService.getState().data, 'getBillingAddress').mockReturnValue(
+ billingAddress,
+ );
- jest.spyOn(checkoutService, 'updateBillingAddress').mockResolvedValue({} as CheckoutSelectors);
+ jest.spyOn(checkoutService, 'updateBillingAddress').mockResolvedValue(
+ {} as CheckoutSelectors,
+ );
jest.spyOn(checkoutService, 'updateCheckout').mockResolvedValue({} as CheckoutSelectors);
- jest.spyOn(checkoutService, 'loadBillingAddressFields').mockResolvedValue({} as CheckoutSelectors);
+ jest.spyOn(checkoutService, 'loadBillingAddressFields').mockResolvedValue(
+ {} as CheckoutSelectors,
+ );
- ComponentTest = props => (
-
-
-
+ ComponentTest = (props) => (
+
+
+
);
});
beforeEach(async () => {
- component = mount();
+ component = mount();
- await new Promise(resolve => process.nextTick(resolve));
+ await new Promise((resolve) => process.nextTick(resolve));
});
it('loads billing fields', () => {
@@ -88,73 +97,71 @@ describe('Billing Component', () => {
});
it('renders header', () => {
- expect(component.find('[data-test="billing-address-heading"]').text())
- .toEqual('Billing Address');
+ expect(component.find('[data-test="billing-address-heading"]').text()).toBe(
+ 'Billing Address',
+ );
});
it('does not render order comments when there are physical items', () => {
- expect(component.find(OrderComments).length)
- .toEqual(0);
+ expect(component.find(OrderComments)).toHaveLength(0);
});
it('renders order comments when there are no physical items', () => {
- jest.spyOn(checkoutService.getState().data, 'getCart')
- .mockReturnValue({
- ...getCart(),
- lineItems: { physicalItems: [] } as unknown as LineItemMap,
- });
+ jest.spyOn(checkoutService.getState().data, 'getCart').mockReturnValue({
+ ...getCart(),
+ lineItems: { physicalItems: [] } as unknown as LineItemMap,
+ });
- component = mount();
+ component = mount();
- expect(component.find(OrderComments).length)
- .toEqual(1);
+ expect(component.find(OrderComments)).toHaveLength(1);
});
it('updates order comment when input value does not match state value', async () => {
- jest.spyOn(checkoutService.getState().data, 'getCart')
- .mockReturnValue({
- ...getCart(),
- lineItems: { physicalItems: [] } as unknown as LineItemMap,
- });
+ jest.spyOn(checkoutService.getState().data, 'getCart').mockReturnValue({
+ ...getCart(),
+ lineItems: { physicalItems: [] } as unknown as LineItemMap,
+ });
- component = mount();
+ component = mount();
- component.find('input[name="orderComment"]')
- .simulate('change', { target: { value: 'foo', name: 'orderComment' } });
+ component
+ .find('input[name="orderComment"]')
+ .simulate('change', { target: { value: 'foo', name: 'orderComment' } });
- component.find('form')
- .simulate('submit');
+ component.find('form').simulate('submit');
- await new Promise(resolve => process.nextTick(resolve));
+ await new Promise((resolve) => process.nextTick(resolve));
expect(checkoutService.updateCheckout).toHaveBeenCalledWith({ customerMessage: 'foo' });
expect(defaultProps.navigateNextStep).toHaveBeenCalled();
});
it('does not render BillingForm while loading billing countries', () => {
- jest.spyOn(checkoutService.getState().statuses, 'isLoadingBillingCountries')
- .mockReturnValue(true);
+ jest.spyOn(
+ checkoutService.getState().statuses,
+ 'isLoadingBillingCountries',
+ ).mockReturnValue(true);
- component = mount();
+ component = mount();
- expect(component.find(BillingForm).length)
- .toEqual(0);
+ expect(component.find(BillingForm)).toHaveLength(0);
});
it('renders BillingForm with expected props', () => {
- expect(component.find(BillingForm).props())
- .toEqual(expect.objectContaining({
+ expect(component.find(BillingForm).props()).toEqual(
+ expect.objectContaining({
billingAddress,
customer: getCustomer(),
countries: getCountries(),
- }));
+ }),
+ );
});
it('calls updateBillingAddress and navigateNextStep when form is submitted and valid', async () => {
- component.find('form')
- .simulate('submit');
+ component.find('form').simulate('submit');
- await new Promise(resolve => process.nextTick(resolve));
+ await new Promise((resolve) => process.nextTick(resolve));
expect(checkoutService.updateBillingAddress).toHaveBeenCalledWith({
address1: '12345 Testing Way',
@@ -177,15 +184,12 @@ describe('Billing Component', () => {
it('calls unhandled error handler when there is error that is not handled by component', async () => {
const error = new Error();
- jest.spyOn(checkoutService, 'updateBillingAddress')
- .mockRejectedValue(error);
+ jest.spyOn(checkoutService, 'updateBillingAddress').mockRejectedValue(error);
- component.find('form')
- .simulate('submit');
+ component.find('form').simulate('submit');
- await new Promise(resolve => process.nextTick(resolve));
+ await new Promise((resolve) => process.nextTick(resolve));
- expect(defaultProps.onUnhandledError)
- .toHaveBeenCalledWith(error);
+ expect(defaultProps.onUnhandledError).toHaveBeenCalledWith(error);
});
});
diff --git a/packages/core/src/app/billing/Billing.tsx b/packages/core/src/app/billing/Billing.tsx
index 3992a94623..123e00634e 100644
--- a/packages/core/src/app/billing/Billing.tsx
+++ b/packages/core/src/app/billing/Billing.tsx
@@ -1,17 +1,24 @@
-import { Address, CheckoutRequestBody, CheckoutSelectors, Country, Customer, FormField } from '@bigcommerce/checkout-sdk';
+import {
+ Address,
+ CheckoutRequestBody,
+ CheckoutSelectors,
+ Country,
+ Customer,
+ FormField,
+} from '@bigcommerce/checkout-sdk';
import { noop } from 'lodash';
import React, { Component, ReactNode } from 'react';
import { isEqualAddress, mapAddressFromFormValues } from '../address';
-import { withCheckout, CheckoutContextProps } from '../checkout';
+import { CheckoutContextProps, withCheckout } from '../checkout';
import { EMPTY_ARRAY } from '../common/utility';
import { TranslatedString } from '../locale';
import { getShippableItemsCount } from '../shipping';
import { Legend } from '../ui/form';
import { LoadingOverlay } from '../ui/loading';
-import getBillingMethodId from './getBillingMethodId';
import BillingForm, { BillingFormValues } from './BillingForm';
+import getBillingMethodId from './getBillingMethodId';
export interface BillingProps {
navigateNextStep(): void;
@@ -38,11 +45,7 @@ export interface WithCheckoutBillingProps {
class Billing extends Component {
async componentDidMount(): Promise {
- const {
- initialize,
- onReady = noop,
- onUnhandledError,
- } = this.props;
+ const { initialize, onReady = noop, onUnhandledError } = this.props;
try {
await initialize();
@@ -55,11 +58,7 @@ class Billing extends Component {
}
render(): ReactNode {
- const {
- updateAddress,
- isInitializing,
- ...props
- } = this.props;
+ const { updateAddress, isInitializing, ...props } = this.props;
return (
@@ -69,14 +68,11 @@ class Billing extends Component {
-
+
@@ -133,11 +129,7 @@ function mapToBillingProps({
getBillingAddressFields,
getBillingCountries,
},
- statuses: {
- isLoadingBillingCountries,
- isUpdatingBillingAddress,
- isUpdatingCheckout,
- },
+ statuses: { isLoadingBillingCountries, isUpdatingBillingAddress, isUpdatingCheckout },
} = checkoutState;
const config = getConfig();
@@ -149,11 +141,7 @@ function mapToBillingProps({
return null;
}
- const {
- enableOrderComments,
- googleMapsApiKey,
- features,
- } = config.checkoutSettings;
+ const { enableOrderComments, googleMapsApiKey, features } = config.checkoutSettings;
const countriesWithAutocomplete = ['US', 'CA', 'AU', 'NZ'];
diff --git a/packages/core/src/app/billing/BillingForm.spec.tsx b/packages/core/src/app/billing/BillingForm.spec.tsx
index 2e38062e50..382b1daf0c 100644
--- a/packages/core/src/app/billing/BillingForm.spec.tsx
+++ b/packages/core/src/app/billing/BillingForm.spec.tsx
@@ -43,14 +43,14 @@ describe('BillingForm Component', () => {
beforeEach(() => {
component = mount(
-
-
-
+
+
+ ,
);
});
it('renders form with expected id', () => {
- expect(component.find('fieldset#checkoutBillingAddress').length).toEqual(1);
+ expect(component.find('fieldset#checkoutBillingAddress')).toHaveLength(1);
});
it('renders form with static address and custom fields', () => {
@@ -60,63 +60,66 @@ describe('BillingForm Component', () => {
};
component = mount(
-
-
-
+
+
+ ,
);
- expect(component.find(StaticBillingAddress).length).toEqual(1);
- expect(component.find(AddressSelect).length).toEqual(0);
- expect(component.find(DynamicFormField).length).toEqual(4);
+ expect(component.find(StaticBillingAddress)).toHaveLength(1);
+ expect(component.find(AddressSelect)).toHaveLength(0);
+ expect(component.find(DynamicFormField)).toHaveLength(4);
});
it('renders addresses', () => {
- expect(component.find('fieldset#billingAddresses').length).toEqual(1);
- expect(component.find(AddressSelect).props()).toEqual(expect.objectContaining({
- addresses: getCustomer().addresses,
- }));
+ expect(component.find('fieldset#billingAddresses')).toHaveLength(1);
+ expect(component.find(AddressSelect).props()).toEqual(
+ expect.objectContaining({
+ addresses: getCustomer().addresses,
+ }),
+ );
});
it('does not render address form when selected customer address is valid', () => {
component = mount(
-
+
-
+ ,
);
- expect(component.find(AddressForm).length).toEqual(0);
+ expect(component.find(AddressForm)).toHaveLength(0);
});
it('renders address form when selected customer address is not valid', () => {
component = mount(
-
+
-
+ ,
);
- expect(component.find(AddressForm).length).toEqual(1);
+ expect(component.find(AddressForm)).toHaveLength(1);
});
it('renders address form', () => {
- expect(component.find(AddressForm).props()).toEqual(expect.objectContaining({
- countries: getCountries(),
- }));
+ expect(component.find(AddressForm).props()).toEqual(
+ expect.objectContaining({
+ countries: getCountries(),
+ }),
+ );
});
it('calls handle submit when form is submitted and valid', async () => {
- component.find('form')
- .simulate('submit');
+ component.find('form').simulate('submit');
- await new Promise(resolve => process.nextTick(resolve));
+ await new Promise((resolve) => process.nextTick(resolve));
expect(defaultProps.onSubmit).toHaveBeenCalledWith({
address1: '12345 Testing Way',
@@ -136,13 +139,13 @@ describe('BillingForm Component', () => {
});
it('calls does not call handle submit when form is submitted and invalid', async () => {
- component.find('input#firstNameInput')
+ component
+ .find('input#firstNameInput')
.simulate('change', { target: { value: '', name: 'firstName' } });
- component.find('form')
- .simulate('submit');
+ component.find('form').simulate('submit');
- await new Promise(resolve => process.nextTick(resolve));
+ await new Promise((resolve) => process.nextTick(resolve));
expect(defaultProps.onSubmit).not.toHaveBeenCalled();
});
diff --git a/packages/core/src/app/billing/BillingForm.tsx b/packages/core/src/app/billing/BillingForm.tsx
index b5eecb6843..75b209750a 100644
--- a/packages/core/src/app/billing/BillingForm.tsx
+++ b/packages/core/src/app/billing/BillingForm.tsx
@@ -1,11 +1,25 @@
-import { Address, CheckoutSelectors, Country, Customer, FormField } from '@bigcommerce/checkout-sdk';
-import { withFormik, FormikProps } from 'formik';
+import {
+ Address,
+ CheckoutSelectors,
+ Country,
+ Customer,
+ FormField,
+} from '@bigcommerce/checkout-sdk';
+import { FormikProps, withFormik } from 'formik';
import React, { createRef, PureComponent, ReactNode, RefObject } from 'react';
import { lazy } from 'yup';
-import { getAddressFormFieldsValidationSchema, getTranslateAddressError, isValidCustomerAddress, mapAddressToFormValues, AddressForm, AddressFormValues, AddressSelect } from '../address';
+import {
+ AddressForm,
+ AddressFormValues,
+ AddressSelect,
+ getAddressFormFieldsValidationSchema,
+ getTranslateAddressError,
+ isValidCustomerAddress,
+ mapAddressToFormValues,
+} from '../address';
import { getCustomFormFieldsValidationSchema } from '../formFields';
-import { withLanguage, TranslatedString, WithLanguageProps } from '../locale';
+import { TranslatedString, withLanguage, WithLanguageProps } from '../locale';
import { OrderComments } from '../orderComments';
import { Button, ButtonVariant } from '../ui/button';
import { Fieldset, Form } from '../ui/form';
@@ -35,7 +49,10 @@ interface BillingFormState {
isResettingAddress: boolean;
}
-class BillingForm extends PureComponent, BillingFormState> {
+class BillingForm extends PureComponent<
+ BillingFormProps & WithLanguageProps & FormikProps,
+ BillingFormState
+> {
state: BillingFormState = {
isResettingAddress: false,
};
@@ -61,56 +78,66 @@ class BillingForm extends PureComponent custom);
const hasCustomFormFields = customFormFields.length > 0;
- const editableFormFields = shouldRenderStaticAddress && hasCustomFormFields ? customFormFields : allFormFields;
+ const editableFormFields =
+ shouldRenderStaticAddress && hasCustomFormFields ? customFormFields : allFormFields;
const { isResettingAddress } = this.state;
const hasAddresses = addresses && addresses.length > 0;
- const hasValidCustomerAddress = billingAddress &&
- isValidCustomerAddress(billingAddress, addresses, getFields(billingAddress.countryCode));
+ const hasValidCustomerAddress =
+ billingAddress &&
+ isValidCustomerAddress(
+ billingAddress,
+ addresses,
+ getFields(billingAddress.countryCode),
+ );
return (