Skip to content

Commit

Permalink
fix(core): Clear shippingLines if no eligible ShippingMethods exist
Browse files Browse the repository at this point in the history
Closes #1195
  • Loading branch information
michaelbromley committed Dec 2, 2021
1 parent da9e2ce commit f9bc532
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 28 deletions.
15 changes: 15 additions & 0 deletions packages/core/e2e/fixtures/test-shipping-eligibility-checkers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { ShippingEligibilityChecker } from '@vendure/core';

export const countryCodeShippingEligibilityChecker = new ShippingEligibilityChecker({
code: 'country-code-shipping-eligibility-checker',
description: [{ languageCode: LanguageCode.en, value: 'Country Shipping Eligibility Checker' }],
args: {
countryCode: {
type: 'string',
},
},
check: (ctx, order, args) => {
return order.shippingAddress?.countryCode === args.countryCode;
},
});
30 changes: 15 additions & 15 deletions packages/core/e2e/graphql/generated-e2e-admin-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6354,6 +6354,12 @@ export type GetTaxRatesQuery = {
taxRates: Pick<TaxRateList, 'totalItems'> & { items: Array<TaxRateFragment> };
};

export type GetShippingMethodListQueryVariables = Exact<{ [key: string]: never }>;

export type GetShippingMethodListQuery = {
shippingMethods: Pick<ShippingMethodList, 'totalItems'> & { items: Array<ShippingMethodFragment> };
};

export type CancelJobMutationVariables = Exact<{
id: Scalars['ID'];
}>;
Expand Down Expand Up @@ -6780,12 +6786,6 @@ export type LogoutMutationVariables = Exact<{ [key: string]: never }>;

export type LogoutMutation = { logout: Pick<Success, 'success'> };

export type GetShippingMethodListQueryVariables = Exact<{ [key: string]: never }>;

export type GetShippingMethodListQuery = {
shippingMethods: Pick<ShippingMethodList, 'totalItems'> & { items: Array<ShippingMethodFragment> };
};

export type GetShippingMethodQueryVariables = Exact<{
id: Scalars['ID'];
}>;
Expand Down Expand Up @@ -8696,6 +8696,15 @@ export namespace GetTaxRates {
export type Items = NonNullable<NonNullable<NonNullable<GetTaxRatesQuery['taxRates']>['items']>[number]>;
}

export namespace GetShippingMethodList {
export type Variables = GetShippingMethodListQueryVariables;
export type Query = GetShippingMethodListQuery;
export type ShippingMethods = NonNullable<GetShippingMethodListQuery['shippingMethods']>;
export type Items = NonNullable<
NonNullable<NonNullable<GetShippingMethodListQuery['shippingMethods']>['items']>[number]
>;
}

export namespace CancelJob {
export type Variables = CancelJobMutationVariables;
export type Mutation = CancelJobMutation;
Expand Down Expand Up @@ -9152,15 +9161,6 @@ export namespace Logout {
export type Logout = NonNullable<LogoutMutation['logout']>;
}

export namespace GetShippingMethodList {
export type Variables = GetShippingMethodListQueryVariables;
export type Query = GetShippingMethodListQuery;
export type ShippingMethods = NonNullable<GetShippingMethodListQuery['shippingMethods']>;
export type Items = NonNullable<
NonNullable<NonNullable<GetShippingMethodListQuery['shippingMethods']>['items']>[number]
>;
}

export namespace GetShippingMethod {
export type Variables = GetShippingMethodQueryVariables;
export type Query = GetShippingMethodQuery;
Expand Down
11 changes: 11 additions & 0 deletions packages/core/e2e/graphql/shared-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -922,3 +922,14 @@ export const GET_TAX_RATES_LIST = gql`
}
${TAX_RATE_FRAGMENT}
`;
export const GET_SHIPPING_METHOD_LIST = gql`
query GetShippingMethodList {
shippingMethods {
items {
...ShippingMethod
}
totalItems
}
}
${SHIPPING_METHOD_FRAGMENT}
`;
13 changes: 1 addition & 12 deletions packages/core/e2e/shipping-method.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
import {
CREATE_SHIPPING_METHOD,
DELETE_SHIPPING_METHOD,
GET_SHIPPING_METHOD_LIST,
UPDATE_SHIPPING_METHOD,
} from './graphql/shared-definitions';

Expand Down Expand Up @@ -339,18 +340,6 @@ describe('ShippingMethod resolver', () => {
});
});

const GET_SHIPPING_METHOD_LIST = gql`
query GetShippingMethodList {
shippingMethods {
items {
...ShippingMethod
}
totalItems
}
}
${SHIPPING_METHOD_FRAGMENT}
`;

const GET_SHIPPING_METHOD = gql`
query GetShippingMethod($id: ID!) {
shippingMethod(id: $id) {
Expand Down
149 changes: 148 additions & 1 deletion packages/core/e2e/shop-order.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
/* tslint:disable:no-non-null-assertion */
import { pick } from '@vendure/common/lib/pick';
import { Asset, mergeConfig } from '@vendure/core';
import {
Asset,
defaultShippingCalculator,
defaultShippingEligibilityChecker,
mergeConfig,
} from '@vendure/core';
import { createErrorResultGuard, createTestEnvironment, ErrorResultGuard } from '@vendure/testing';
import gql from 'graphql-tag';
import path from 'path';

import { initialData } from '../../../e2e-common/e2e-initial-data';
import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
import { manualFulfillmentHandler } from '../src/index';

import {
testErrorPaymentMethod,
testFailingPaymentMethod,
testSuccessfulPaymentMethod,
} from './fixtures/test-payment-methods';
import { countryCodeShippingEligibilityChecker } from './fixtures/test-shipping-eligibility-checkers';
import {
AttemptLogin,
CreateAddressInput,
CreateShippingMethod,
CreateShippingMethodInput,
DeleteProduct,
DeleteProductVariant,
DeleteShippingMethod,
GetCountryList,
GetCustomer,
GetCustomerList,
GetShippingMethodList,
LanguageCode,
UpdateCountry,
UpdateProduct,
UpdateProductVariants,
Expand Down Expand Up @@ -53,11 +65,14 @@ import {
} from './graphql/generated-e2e-shop-types';
import {
ATTEMPT_LOGIN,
CREATE_SHIPPING_METHOD,
DELETE_PRODUCT,
DELETE_PRODUCT_VARIANT,
DELETE_SHIPPING_METHOD,
GET_COUNTRY_LIST,
GET_CUSTOMER,
GET_CUSTOMER_LIST,
GET_SHIPPING_METHOD_LIST,
UPDATE_COUNTRY,
UPDATE_PRODUCT,
UPDATE_PRODUCT_VARIANTS,
Expand Down Expand Up @@ -96,6 +111,12 @@ describe('Shop orders', () => {
testErrorPaymentMethod,
],
},
shippingOptions: {
shippingEligibilityCheckers: [
defaultShippingEligibilityChecker,
countryCodeShippingEligibilityChecker,
],
},
customFields: {
Order: [
{ name: 'giftWrap', type: 'boolean', defaultValue: false },
Expand Down Expand Up @@ -1843,6 +1864,132 @@ describe('Shop orders', () => {
expect(transitionOrderToState!.errorCode).toBe(ErrorCode.ORDER_STATE_TRANSITION_ERROR);
});
});

// https://github.com/vendure-ecommerce/vendure/issues/1195
describe('shipping method invalidation', () => {
let GBShippingMethodId: string;
let ATShippingMethodId: string;

beforeAll(async () => {
// First we will remove all ShippingMethods and set up 2 specialized ones
const { shippingMethods } = await adminClient.query<GetShippingMethodList.Query>(
GET_SHIPPING_METHOD_LIST,
);
for (const method of shippingMethods.items) {
await adminClient.query<DeleteShippingMethod.Mutation, DeleteShippingMethod.Variables>(
DELETE_SHIPPING_METHOD,
{
id: method.id,
},
);
}

function createCountryCodeShippingMethodInput(countryCode: string): CreateShippingMethodInput {
return {
code: `${countryCode}-shipping`,
translations: [
{ languageCode: LanguageCode.en, name: `${countryCode} shipping`, description: '' },
],
fulfillmentHandler: manualFulfillmentHandler.code,
checker: {
code: countryCodeShippingEligibilityChecker.code,
arguments: [{ name: 'countryCode', value: countryCode }],
},
calculator: {
code: defaultShippingCalculator.code,
arguments: [
{ name: 'rate', value: '1000' },
{ name: 'taxRate', value: '0' },
{ name: 'includesTax', value: 'auto' },
],
},
};
}

// Now create 2 shipping methods, valid only for a single country
const result1 = await adminClient.query<
CreateShippingMethod.Mutation,
CreateShippingMethod.Variables
>(CREATE_SHIPPING_METHOD, {
input: createCountryCodeShippingMethodInput('GB'),
});
GBShippingMethodId = result1.createShippingMethod.id;
const result2 = await adminClient.query<
CreateShippingMethod.Mutation,
CreateShippingMethod.Variables
>(CREATE_SHIPPING_METHOD, {
input: createCountryCodeShippingMethodInput('AT'),
});
ATShippingMethodId = result2.createShippingMethod.id;

// Now create an order to GB and set the GB shipping method
const { addItemToOrder } = await shopClient.query<
AddItemToOrder.Mutation,
AddItemToOrder.Variables
>(ADD_ITEM_TO_ORDER, {
productVariantId: 'T_1',
quantity: 1,
});
await shopClient.query<SetCustomerForOrder.Mutation, SetCustomerForOrder.Variables>(
SET_CUSTOMER,
{
input: {
emailAddress: 'test-2@test.com',
firstName: 'Test',
lastName: 'Person 2',
},
},
);
await shopClient.query<SetShippingAddress.Mutation, SetShippingAddress.Variables>(
SET_SHIPPING_ADDRESS,
{
input: {
streetLine1: '12 the street',
countryCode: 'GB',
},
},
);
await shopClient.query<SetShippingMethod.Mutation, SetShippingMethod.Variables>(
SET_SHIPPING_METHOD,
{
id: GBShippingMethodId,
},
);
});

it('if selected method no longer eligible, next best is set automatically', async () => {
const result1 = await shopClient.query<GetActiveOrder.Query>(GET_ACTIVE_ORDER);
expect(result1.activeOrder?.shippingLines[0].shippingMethod.id).toBe(GBShippingMethodId);

await shopClient.query<SetShippingAddress.Mutation, SetShippingAddress.Variables>(
SET_SHIPPING_ADDRESS,
{
input: {
streetLine1: '12 the street',
countryCode: 'AT',
},
},
);

const result2 = await shopClient.query<GetActiveOrder.Query>(GET_ACTIVE_ORDER);
expect(result2.activeOrder?.shippingLines[0].shippingMethod.id).toBe(ATShippingMethodId);
});

it('if no method is eligible, shipping lines are cleared', async () => {
await shopClient.query<SetShippingAddress.Mutation, SetShippingAddress.Variables>(
SET_SHIPPING_ADDRESS,
{
input: {
streetLine1: '12 the street',
countryCode: 'US',
},
},
);

const result = await shopClient.query<GetActiveOrder.Query>(GET_ACTIVE_ORDER);
expect(result.activeOrder?.shippingLines).toEqual([]);
});
});
});

const GET_ORDER_CUSTOM_FIELDS = gql`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,8 @@ export class OrderCalculator {
taxRate: cheapest.result.taxRate,
},
];
} else {
order.shippingLines = [];
}
}

Expand Down

0 comments on commit f9bc532

Please sign in to comment.