Skip to content

Commit

Permalink
fix(checkout): correctly switch package type based on shipping methods
Browse files Browse the repository at this point in the history
  • Loading branch information
EdieLemoine committed Jun 29, 2024
1 parent 9940421 commit 109bd99
Show file tree
Hide file tree
Showing 33 changed files with 217 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ exports[`exports > exports from index.ts 1`] = `
"_",
"createPdkCheckout",
"debounce",
"defaultGetPackageType",
"defaultUpdateDeliveryOptions",
"deliveryOptionsIsRendered",
"getDeliveryOptionsAddress",
"getEnabledShippingMethods",
"getResolvedSettings",
"initializeCheckoutDeliveryOptions",
"initializeCheckoutSeparateAddressFields",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ exports[`exports > exports from index.ts 1`] = `
"_",
"createPdkCheckout",
"debounce",
"defaultGetPackageType",
"defaultUpdateDeliveryOptions",
"deliveryOptionsIsRendered",
"getDeliveryOptionsAddress",
"getEnabledShippingMethods",
"getResolvedSettings",
"initializeCheckoutDeliveryOptions",
"initializeCheckoutSeparateAddressFields",
Expand Down
2 changes: 2 additions & 0 deletions apps/checkout/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type {
PdkCheckoutConfig,
PdkCheckoutConfigInput,
PdkCheckoutForm,
PdkFormData,
StoreCallbackUpdate,
} from '@myparcel-pdk/checkout-common';

Expand All @@ -29,6 +30,7 @@ export {
PdkUtil as Util,
globals as _,
createPdkCheckout,
getEnabledShippingMethods,
useCheckoutStore,
useEvent,
usePdkCheckout,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ exports[`exports > exports from index.ts 1`] = `
"createConfig",
"createEventName",
"createPdkCheckout",
"defaultFormChange",
"defaultGetAddressType",
"defaultGetFormData",
"defaultHasDeliveryOptions",
"doRequest",
"eventCheckoutUpdate",
"eventCheckoutUpdated",
Expand All @@ -33,6 +37,7 @@ exports[`exports > exports from index.ts 1`] = `
"getAddressFieldValue",
"getAddressType",
"getElement",
"getEnabledShippingMethods",
"getFieldValue",
"getFrontendContext",
"globals",
Expand Down
17 changes: 17 additions & 0 deletions libs/checkout-common/src/__tests__/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {type PdkFormData} from '../types';
import {AddressType} from '../data';

export const DEFAULT_MOCK_FORM_DATA = Object.freeze({
'address-type': AddressType.Billing,
'b-address1': 'Straatnaam 12e',
'b-address2': '',
'b-city': 'Amsterdam',
'b-country': 'NL',
'b-postal-code': '1234AB',
's-address1': 'Straatnaam 12e',
's-address2': '',
's-city': 'Amsterdam',
's-country': 'NL',
's-postal-code': '1234AB',
'shipping-method': 'standard',
} satisfies PdkFormData);
10 changes: 9 additions & 1 deletion libs/checkout-common/src/__tests__/getMockCheckoutContext.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {vi} from 'vitest';
import {FrontendEndpoint} from '@myparcel-pdk/common';
import {PackageTypeName} from '@myparcel/constants';
import {type CheckoutAppCheckoutContext} from '../types';

export const getMockCheckoutContext = vi.fn(
Expand All @@ -22,7 +23,14 @@ export const getMockCheckoutContext = vi.fn(
},
...context?.settings?.actions,
},
allowedShippingMethods: [],
allowedShippingMethods: {
'-1': ['standard', 'free_shipping'],
[PackageTypeName.Package]: ['flat_rate:1'],
[PackageTypeName.PackageSmall]: ['flat_rate:2'],
[PackageTypeName.Mailbox]: ['flat_rate:3', 'flat_rate:4'],
[PackageTypeName.DigitalStamp]: ['flat_rate:5'],
[PackageTypeName.Letter]: ['flat_rate:6'],
},
carriersWithTaxFields: [],
countriesWithSeparateAddressFields: [],
hiddenInputName: '',
Expand Down
2 changes: 2 additions & 0 deletions libs/checkout-common/src/__tests__/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export * from './constants';
export * from './getMockCheckoutContext';
export * from './getMockFormData';
export * from './getMockPdkCheckoutConfig';
export * from './mockDeliveryOptionsElement';
export * from './mockPdkCheckout';
export * from './mockShippingMethod';
export * from './spies';
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const mockDeliveryOptionsElement = (): void => {
const wrapper = document.createElement('div');
const element = document.createElement('div');

form.id = 'test-wrapper';
wrapper.id = 'delivery-options-wrapper';
element.id = 'delivery-options';

Expand Down
11 changes: 11 additions & 0 deletions libs/checkout-common/src/__tests__/mockPdkCheckout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@ import {createPdkCheckout} from '../createPdkCheckout';
import {mockDeliveryOptionsElement} from './mockDeliveryOptionsElement';
import {getMockPdkCheckoutConfig} from './getMockPdkCheckoutConfig';

function reset() {
// Clear the window object
// @ts-expect-error this is correct for testing
window.MyParcelPdk = undefined;

// Delete any wrappers added by previous tests
document.getElementById('test-wrapper')?.remove();
}

export const mockPdkCheckout = (config?: Partial<PdkCheckoutConfigInput>, includeElements = true): Promise<void> => {
reset();

return new Promise((resolve, reject) => {
if (includeElements) {
mockDeliveryOptionsElement();
Expand Down
8 changes: 8 additions & 0 deletions libs/checkout-common/src/__tests__/mockShippingMethod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {getFormDataSpy} from './spies';

export const mockShippingMethod = (shippingMethod: string): void => {
getFormDataSpy.mockReturnValue({
...getFormDataSpy(),
'shipping-method': shippingMethod,
});
};
20 changes: 3 additions & 17 deletions libs/checkout-common/src/__tests__/spies.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
import {vi} from 'vitest';
import {AddressType} from '../data';
import {type PdkFormData} from '../types';
import {DEFAULT_MOCK_FORM_DATA} from './constants';

export const doRequestSpy = vi.fn();

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
export const getFormSpy = vi.fn(() => document.querySelector<HTMLFormElement>('form')!);

export const getFormDataSpy = vi.fn(
(): Record<string, string> => ({
'address-type': AddressType.Billing,
'b-address1': 'Straatnaam 12e',
'b-address2': '',
'b-city': 'Amsterdam',
'b-country': 'NL',
'b-postal-code': '1234AB',
's-address1': 'Straatnaam 12e',
's-address2': '',
's-city': 'Amsterdam',
's-country': 'NL',
's-postal-code': '1234AB',
'shipping-method': 'shipping-method',
}),
);
export const getFormDataSpy = vi.fn((): PdkFormData => DEFAULT_MOCK_FORM_DATA);

export const hasAddressTypeSpy = vi.fn(() => true);

Expand Down
1 change: 1 addition & 0 deletions libs/checkout-common/src/data/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export enum PdkUtil {
GetAddressFieldValue = 'getAddressFieldValue',
GetElement = 'getElement',
GetFieldValue = 'getFieldValue',
IsEnumValue = 'isEnumValue',
IsOfType = 'isOfType',
SetFieldValue = 'setFieldValue',
TriggerEvent = 'triggerEvent',
Expand Down
9 changes: 9 additions & 0 deletions libs/checkout-common/src/defaults/defaultFormChange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {useConfig} from '../utils';
import {type PdkCheckoutConfig} from '../types';

export const defaultFormChange = ((callback) => {
const config = useConfig();
const form = config.getForm();

form.addEventListener('change', callback);
}) satisfies PdkCheckoutConfig['formChange'];
4 changes: 4 additions & 0 deletions libs/checkout-common/src/defaults/defaultGetAddressType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import {type PdkCheckoutConfig} from '../types';
import {type AddressType} from '../data';

export const defaultGetAddressType = ((value) => value as AddressType) satisfies PdkCheckoutConfig['getAddressType'];
11 changes: 11 additions & 0 deletions libs/checkout-common/src/defaults/defaultGetFormData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {useConfig} from '../utils';
import {type PdkCheckoutConfig} from '../types';

export const defaultGetFormData = (() => {
const config = useConfig();
const form = config.getForm();

const formData = new FormData(form);

return Object.fromEntries(formData.entries());
}) satisfies PdkCheckoutConfig['getFormData'];

Check warning on line 11 in libs/checkout-common/src/defaults/defaultGetFormData.ts

View check run for this annotation

Codecov / codecov/patch

libs/checkout-common/src/defaults/defaultGetFormData.ts#L5-L11

Added lines #L5 - L11 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {getEnabledShippingMethods} from '../utils';
import {type PdkCheckoutConfig} from '../types';

export const defaultHasDeliveryOptions = ((shippingMethod: string): boolean => {
const enabledShippingMethods = getEnabledShippingMethods();

return enabledShippingMethods.some((method) => shippingMethod === method);
}) satisfies PdkCheckoutConfig['hasDeliveryOptions'];

Check warning on line 8 in libs/checkout-common/src/defaults/defaultHasDeliveryOptions.ts

View check run for this annotation

Codecov / codecov/patch

libs/checkout-common/src/defaults/defaultHasDeliveryOptions.ts#L5-L8

Added lines #L5 - L8 were not covered by tests
4 changes: 4 additions & 0 deletions libs/checkout-common/src/defaults/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './defaultFormChange';
export * from './defaultGetAddressType';
export * from './defaultGetFormData';
export * from './defaultHasDeliveryOptions';
1 change: 1 addition & 0 deletions libs/checkout-common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export * as tests from './__tests__';
export * from './constants';
export * from './createPdkCheckout';
export * from './data';
export * from './defaults';
export * as globals from './globals';
export * from './init';
export * from './listeners';
Expand Down
28 changes: 5 additions & 23 deletions libs/checkout-common/src/init/createConfig.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,11 @@
import {useConfig, useSettings} from '../utils';
import {type PdkCheckoutConfig, type PdkCheckoutConfigInput} from '../types';
import {type AddressType} from '../data';
import {defaultFormChange, defaultGetAddressType, defaultGetFormData, defaultHasDeliveryOptions} from '../defaults';

export const createConfig = (config: PdkCheckoutConfigInput): PdkCheckoutConfig => ({
formChange(callback) {
const form = useConfig().getForm();
form.addEventListener('change', callback);
},

getAddressType(value) {
return value as AddressType;
},

getFormData() {
const form = useConfig().getForm();
const formData = new FormData(form);

return Object.fromEntries(formData.entries());
},

hasDeliveryOptions(shippingMethod: string): boolean {
const settings = useSettings();

return settings.allowedShippingMethods.some((method) => shippingMethod === method);
},
formChange: defaultFormChange,
getAddressType: defaultGetAddressType,
getFormData: defaultGetFormData,
hasDeliveryOptions: defaultHasDeliveryOptions,

...config,
selectors: {
Expand Down
3 changes: 2 additions & 1 deletion libs/checkout-common/src/init/setupGlobals.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// eslint-disable-next-line max-lines-per-function
import {isOfType} from '@myparcel/ts-utils';
import {isEnumValue, isOfType} from '@myparcel/ts-utils';
import {
doRequest,
fieldsEqual,
Expand Down Expand Up @@ -66,6 +66,7 @@ export const setupGlobals = (config: PdkCheckoutConfig): void => {
getAddressFieldValue,
getElement,
getFieldValue,
isEnumValue,
isOfType,
setFieldValue,
triggerEvent,
Expand Down
6 changes: 3 additions & 3 deletions libs/checkout-common/src/listeners/updateCheckoutForm.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {getAddressType, useCheckoutStore, useConfig} from '../utils';
import {type PdkCheckoutForm} from '../types';
import {type PdkCheckoutForm, type PdkFormData} from '../types';
import {type AddressField, AddressType, type PdkField} from '../data';

function getEntry(data: Record<string, FormDataEntryValue>, value: undefined | string): string {
const getEntry = (data: PdkFormData, value: undefined | string): string => {
return (data[value as string] as string | undefined) ?? '';
}
};

export const updateCheckoutForm = (): void => {
const checkout = useCheckoutStore();
Expand Down
10 changes: 6 additions & 4 deletions libs/checkout-common/src/types/checkout.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {type FrontendEndpoint} from '@myparcel-pdk/common';
import {type FrontendEndpoint, type ShippingMethodTypeMap} from '@myparcel-pdk/common';
import {type PromiseOr} from '@myparcel/ts-utils';
import {type InputDeliveryOptionsConfiguration} from '@myparcel/delivery-options';
import {type CarrierName} from '@myparcel/constants';
Expand All @@ -10,13 +10,15 @@ import {
} from './endpoints.types';
import {type AddressFields} from './address.types';

export type PdkFormData = Record<string, FormDataEntryValue | undefined>;

export type PdkCheckoutConfigInput = Omit<
PdkCheckoutConfig,
'selectors' | 'formChange' | 'getFormData' | 'getAddressType' | 'hasDeliveryOptions'
> & {
formChange?(callback: () => void): void;
getAddressType?(value: unknown): AddressType;
getFormData?(): Record<string, FormDataEntryValue>;
getFormData?(): PdkFormData;
hasDeliveryOptions?(shippingMethod: string): PromiseOr<boolean>;
selectors: Omit<PdkCheckoutConfig['selectors'], 'deliveryOptions'> & {
deliveryOptions?: string;
Expand Down Expand Up @@ -60,7 +62,7 @@ export interface PdkCheckoutConfig {
/**
* Get the form data.
*/
getFormData(): Record<string, FormDataEntryValue>;
getFormData(): PdkFormData;

/**
* Check if the address type is available.
Expand Down Expand Up @@ -104,7 +106,7 @@ export type CheckoutSettings = {
};

// Delivery options
allowedShippingMethods: string[];
allowedShippingMethods: ShippingMethodTypeMap;
hasDeliveryOptions: boolean;
hiddenInputName: string;

Expand Down
3 changes: 2 additions & 1 deletion libs/checkout-common/src/types/global.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {type isOfType, type PromiseOr} from '@myparcel/ts-utils';
import {type isEnumValue, type isOfType, type PromiseOr} from '@myparcel/ts-utils';
import {
type doRequest,
type fieldsEqual,
Expand Down Expand Up @@ -33,6 +33,7 @@ export interface PdkUtils extends AdditionalUtils {
[PdkUtil.GetAddressField]: typeof getAddressField;
[PdkUtil.GetElement]: typeof getElement;
[PdkUtil.GetFieldValue]: typeof getFieldValue;
[PdkUtil.IsEnumValue]: typeof isEnumValue;
[PdkUtil.IsOfType]: typeof isOfType;
[PdkUtil.SetFieldValue]: typeof setFieldValue;
[PdkUtil.TriggerEvent]: typeof triggerEvent;
Expand Down
9 changes: 9 additions & 0 deletions libs/checkout-common/src/utils/getEnabledShippingMethods.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {useSettings} from './useSettings';

export const getEnabledShippingMethods = (): string[] => {
const settings = useSettings();
// No need to filter keys, 0 (off) is not included in the object
const entries = Object.entries(settings.allowedShippingMethods);

return entries.flatMap(([, value]) => value);
};

Check warning on line 9 in libs/checkout-common/src/utils/getEnabledShippingMethods.ts

View check run for this annotation

Codecov / codecov/patch

libs/checkout-common/src/utils/getEnabledShippingMethods.ts#L4-L9

Added lines #L4 - L9 were not covered by tests
1 change: 1 addition & 0 deletions libs/checkout-common/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './getEnabledShippingMethods';
export * from './getFrontendContext';
export * from './global';
export * from './hasAddressType';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ exports[`exports > exports from index.ts 1`] = `
"DeliveryOptionsMode",
"PdkDeliveryOptionsEvent",
"debounce",
"defaultGetPackageType",
"defaultUpdateDeliveryOptions",
"deliveryOptionsIsRendered",
"getDeliveryOptionsAddress",
"getResolvedSettings",
Expand Down
Loading

0 comments on commit 109bd99

Please sign in to comment.