From 1fb7b7c81c9149a17386be667cec818ee841bbdb Mon Sep 17 00:00:00 2001 From: Edie Lemoine Date: Mon, 15 Apr 2024 16:14:07 +0200 Subject: [PATCH] fix: fix non-default package types not working (#216) INT-447 --- .../useDeliveryMomentOptions.spec.ts | 95 +++++++++++++++++++ .../composables/useDeliveryMomentOptions.ts | 21 ++-- apps/delivery-options/src/data/constants.ts | 5 +- libs/shared/src/types/options.types.ts | 7 +- 4 files changed, 111 insertions(+), 17 deletions(-) create mode 100644 apps/delivery-options/src/composables/useDeliveryMomentOptions.spec.ts diff --git a/apps/delivery-options/src/composables/useDeliveryMomentOptions.spec.ts b/apps/delivery-options/src/composables/useDeliveryMomentOptions.spec.ts new file mode 100644 index 00000000..cdf5dfc8 --- /dev/null +++ b/apps/delivery-options/src/composables/useDeliveryMomentOptions.spec.ts @@ -0,0 +1,95 @@ +import {type ComputedRef} from 'vue'; +import {describe, it, expect, beforeEach} from 'vitest'; +import {setActivePinia, createPinia} from 'pinia'; +import {flushPromises} from '@vue/test-utils'; +import { + KEY_CONFIG, + ConfigSetting, + CarrierSetting, + KEY_CARRIER_SETTINGS, + DELIVERY_TYPE_DEFAULT, + PACKAGE_TYPE_DEFAULT, + type SupportedPackageTypeName, + type SelectOption, +} from '@myparcel-do/shared'; +import {CarrierName, PackageTypeName} from '@myparcel/constants'; +import {parseJson} from '../utils'; +import {type SelectedDeliveryMoment} from '../types'; +import {mockSelectedDeliveryOptions, mockDeliveryOptionsConfig} from '../__tests__'; +import {useDeliveryMomentOptions} from './useDeliveryMomentOptions'; + +const setup = async (packageType?: SupportedPackageTypeName): Promise[]>> => { + mockDeliveryOptionsConfig({ + [KEY_CONFIG]: { + [ConfigSetting.ShowDeliveryDate]: true, + [CarrierSetting.AllowDeliveryOptions]: true, + [CarrierSetting.AllowStandardDelivery]: true, + [CarrierSetting.AllowEveningDelivery]: true, + [CarrierSetting.AllowMorningDelivery]: true, + [CarrierSetting.AllowSignature]: true, + [CarrierSetting.AllowOnlyRecipient]: true, + [KEY_CARRIER_SETTINGS]: { + [CarrierName.PostNl]: {}, + [CarrierName.DhlForYou]: {}, + }, + // TODO: allow optional key to be passed with undefined as value + ...(packageType ? {[CarrierSetting.PackageType]: packageType} : {}), + }, + }); + mockSelectedDeliveryOptions(); + + const options = useDeliveryMomentOptions(); + await flushPromises(); + + return options; +}; + +describe('useDeliveryMomentOptions', () => { + beforeEach(() => { + setActivePinia(createPinia()); + }); + + it('returns delivery moment options', async () => { + expect.assertions(8); + const options = await setup(); + + expect(options.value).toHaveLength(1); + + options.value.forEach((option) => { + expect(Object.keys(option)).toEqual(['carrier', 'label', 'price', 'value']); + expect(option.value).toBeTypeOf('string'); + + const parsedValue = parseJson(option.value); + + expect(parsedValue.carrier).toBe(CarrierName.PostNl); + expect(parsedValue.time).not.toBeNull(); + expect(parsedValue.deliveryType).toBe(DELIVERY_TYPE_DEFAULT); + expect(parsedValue.packageType).toBe(PACKAGE_TYPE_DEFAULT); + expect(parsedValue.shipmentOptions).toEqual([]); + }); + }); + + it.each([PackageTypeName.Mailbox, PackageTypeName.DigitalStamp, PackageTypeName.PackageSmall])( + 'returns delivery moment options for different package types', + async (packageType) => { + expect.assertions(8); + + const options = await setup(packageType); + + expect(options.value).toHaveLength(1); + + options.value.forEach((option) => { + expect(Object.keys(option)).toEqual(['carrier', 'label', 'price', 'value']); + expect(option.value).toBeTypeOf('string'); + + const parsedValue = parseJson(option.value); + + expect(parsedValue.carrier).toBe(CarrierName.PostNl); + expect(parsedValue.time).toBeNull(); + expect(parsedValue.deliveryType).toBe(DELIVERY_TYPE_DEFAULT); + expect(parsedValue.packageType).toBe(packageType); + expect(parsedValue.shipmentOptions).toEqual([]); + }); + }, + ); +}); diff --git a/apps/delivery-options/src/composables/useDeliveryMomentOptions.ts b/apps/delivery-options/src/composables/useDeliveryMomentOptions.ts index db1c5b99..875b57e9 100644 --- a/apps/delivery-options/src/composables/useDeliveryMomentOptions.ts +++ b/apps/delivery-options/src/composables/useDeliveryMomentOptions.ts @@ -1,17 +1,12 @@ import {type ComputedRef, computed, toValue} from 'vue'; -import { - type SelectOption, - PACKAGE_TYPE_DEFAULT, - DELIVERY_TYPE_DEFAULT, - type SupportedShipmentOptionName, -} from '@myparcel-do/shared'; +import {type SelectOption, PACKAGE_TYPE_DEFAULT, DELIVERY_TYPE_DEFAULT} from '@myparcel-do/shared'; import {getDeliveryTypePrice, createPackageTypeTranslatable} from '../utils'; import {useConfigStore} from '../stores'; import {SHOWN_SHIPMENT_OPTIONS} from '../data'; import {useResolvedDeliveryMoments} from './useResolvedDeliveryMoments'; import {useActiveCarriers} from './useActiveCarriers'; -export const useDeliveryMomentOptions = (): ComputedRef => { +export const useDeliveryMomentOptions = (): ComputedRef[]> => { const config = useConfigStore(); const deliveryMoments = useResolvedDeliveryMoments(); const activeCarriers = useActiveCarriers(); @@ -21,12 +16,14 @@ export const useDeliveryMomentOptions = (): ComputedRef => { return activeCarriers.value .filter((carrier) => toValue(carrier.hasAnyDelivery) && toValue(carrier.packageTypes).has(config.packageType)) .map((carrier) => { + const resolvedCarrier = toValue(carrier.carrier); + return { - carrier: carrier.name, + carrier: resolvedCarrier.name, label: createPackageTypeTranslatable(config.packageType), - price: getDeliveryTypePrice(DELIVERY_TYPE_DEFAULT, carrier.name), + price: getDeliveryTypePrice(DELIVERY_TYPE_DEFAULT, resolvedCarrier.name), value: JSON.stringify({ - carrier: carrier.name, + carrier: resolvedCarrier.name, date: null, deliveryType: DELIVERY_TYPE_DEFAULT, packageType: config.packageType, @@ -48,9 +45,7 @@ export const useDeliveryMomentOptions = (): ComputedRef => { date: option.date, deliveryType: option.deliveryType, packageType: option.packageType, - shipmentOptions: option.shipmentOptions.filter((option) => - SHOWN_SHIPMENT_OPTIONS.includes(option.name as SupportedShipmentOptionName), - ), + shipmentOptions: option.shipmentOptions.filter((option) => SHOWN_SHIPMENT_OPTIONS.includes(option.name)), }), }; }); diff --git a/apps/delivery-options/src/data/constants.ts b/apps/delivery-options/src/data/constants.ts index 0011024f..7950662c 100644 --- a/apps/delivery-options/src/data/constants.ts +++ b/apps/delivery-options/src/data/constants.ts @@ -29,7 +29,10 @@ export const FIELD_SHIPMENT_OPTIONS = 'shipmentOptions'; */ export const FIELD_PICKUP_LOCATION = 'pickupLocation'; -export const SHOWN_SHIPMENT_OPTIONS = [ShipmentOptionName.Signature, ShipmentOptionName.OnlyRecipient] as const; +export const SHOWN_SHIPMENT_OPTIONS = Object.freeze([ + ShipmentOptionName.Signature, + ShipmentOptionName.OnlyRecipient, +]); export const MAP_MARKER_CLASS_ACTIVE = 'active'; diff --git a/libs/shared/src/types/options.types.ts b/libs/shared/src/types/options.types.ts index d0e509e6..29875b79 100644 --- a/libs/shared/src/types/options.types.ts +++ b/libs/shared/src/types/options.types.ts @@ -1,6 +1,5 @@ import {type AnyTranslatable} from './language.types'; import {type CarrierIdentifier} from './config.types'; -import {type Translation} from './common.types'; export type OptionsProps = { options: SelectOption[]; @@ -20,7 +19,9 @@ interface BaseSelectOption export type SelectOptionValue = string | object | boolean; -export interface SelectOption - extends BaseSelectOption { +export interface SelectOption< + Value extends SelectOptionValue = SelectOptionValue, + T extends AnyTranslatable = AnyTranslatable, +> extends BaseSelectOption { label: T; }