Skip to content

Commit

Permalink
fix(core): Correctly de-duplicate OrderLines with empty custom fields
Browse files Browse the repository at this point in the history
Fixes #512
  • Loading branch information
michaelbromley committed Oct 21, 2020
1 parent 76d2d56 commit ef99c22
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 2 deletions.
106 changes: 105 additions & 1 deletion packages/core/e2e/shop-order.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import gql from 'graphql-tag';
import path from 'path';

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

import {
testErrorPaymentMethod,
Expand Down Expand Up @@ -77,6 +77,7 @@ import {
SET_SHIPPING_METHOD,
TEST_ORDER_FRAGMENT,
TRANSITION_TO_STATE,
UPDATED_ORDER_FRAGMENT,
} from './graphql/shop-definitions';
import { assertThrowsWithMessage } from './utils/assert-throws-with-message';

Expand All @@ -92,6 +93,7 @@ describe('Shop orders', () => {
},
customFields: {
Order: [{ name: 'giftWrap', type: 'boolean', defaultValue: false }],
OrderLine: [{ name: 'notes', type: 'string' }],
},
orderOptions: {
orderItemsLimit: 99,
Expand Down Expand Up @@ -212,6 +214,87 @@ describe('Shop orders', () => {
expect(addItemToOrder!.lines[0].quantity).toBe(3);
});

it('addItemToOrder with equal customFields adds quantity to the existing OrderLine', async () => {
const { addItemToOrder: add1 } = await shopClient.query<AddItemToOrder.Mutation>(
ADD_ITEM_TO_ORDER_WITH_CUSTOM_FIELDS,
{
productVariantId: 'T_2',
quantity: 1,
customFields: {
notes: 'note1',
},
},
);
orderResultGuard.assertSuccess(add1);
expect(add1!.lines.length).toBe(2);
expect(add1!.lines[1].quantity).toBe(1);

const { addItemToOrder: add2 } = await shopClient.query<AddItemToOrder.Mutation>(
ADD_ITEM_TO_ORDER_WITH_CUSTOM_FIELDS,
{
productVariantId: 'T_2',
quantity: 1,
customFields: {
notes: 'note1',
},
},
);
orderResultGuard.assertSuccess(add2);
expect(add2!.lines.length).toBe(2);
expect(add2!.lines[1].quantity).toBe(2);

await shopClient.query<RemoveItemFromOrder.Mutation, RemoveItemFromOrder.Variables>(
REMOVE_ITEM_FROM_ORDER,
{
orderLineId: add2!.lines[1].id,
},
);
});

it('addItemToOrder with different customFields adds quantity to a new OrderLine', async () => {
const { addItemToOrder: add1 } = await shopClient.query<AddItemToOrder.Mutation>(
ADD_ITEM_TO_ORDER_WITH_CUSTOM_FIELDS,
{
productVariantId: 'T_3',
quantity: 1,
customFields: {
notes: 'note2',
},
},
);
orderResultGuard.assertSuccess(add1);
expect(add1!.lines.length).toBe(2);
expect(add1!.lines[1].quantity).toBe(1);

const { addItemToOrder: add2 } = await shopClient.query<AddItemToOrder.Mutation>(
ADD_ITEM_TO_ORDER_WITH_CUSTOM_FIELDS,
{
productVariantId: 'T_3',
quantity: 1,
customFields: {
notes: 'note3',
},
},
);
orderResultGuard.assertSuccess(add2);
expect(add2!.lines.length).toBe(3);
expect(add2!.lines[1].quantity).toBe(1);
expect(add2!.lines[2].quantity).toBe(1);

await shopClient.query<RemoveItemFromOrder.Mutation, RemoveItemFromOrder.Variables>(
REMOVE_ITEM_FROM_ORDER,
{
orderLineId: add2!.lines[1].id,
},
);
await shopClient.query<RemoveItemFromOrder.Mutation, RemoveItemFromOrder.Variables>(
REMOVE_ITEM_FROM_ORDER,
{
orderLineId: add2!.lines[2].id,
},
);
});

it('addItemToOrder errors when going beyond orderItemsLimit', async () => {
const { addItemToOrder } = await shopClient.query<
AddItemToOrder.Mutation,
Expand Down Expand Up @@ -1317,3 +1400,24 @@ const SET_ORDER_CUSTOM_FIELDS = gql`
}
}
`;

export const ADD_ITEM_TO_ORDER_WITH_CUSTOM_FIELDS = gql`
mutation AddItemToOrderWithCustomFields(
$productVariantId: ID!
$quantity: Int!
$customFields: OrderLineCustomFieldsInput
) {
addItemToOrder(
productVariantId: $productVariantId
quantity: $quantity
customFields: $customFields
) {
...UpdatedOrder
... on ErrorResult {
errorCode
message
}
}
}
${UPDATED_ORDER_FRAGMENT}
`;
14 changes: 13 additions & 1 deletion packages/core/src/service/services/order.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ export class OrderService {
let orderLine = order.lines.find(line => {
return (
idsAreEqual(line.productVariant.id, productVariantId) &&
JSON.stringify(line.customFields) === JSON.stringify(customFields)
this.customFieldsAreEqual(customFields, line.customFields)
);
});

Expand Down Expand Up @@ -1070,6 +1070,18 @@ export class OrderService {
});
}

private customFieldsAreEqual(
inputCustomFields: { [key: string]: any } | null | undefined,
existingCustomFields?: { [key: string]: any },
): boolean {
if (inputCustomFields == null && typeof existingCustomFields === 'object') {
// A null value for an OrderLine customFields input is the equivalent
// of every property of an existing customFields object being null.
return Object.values(existingCustomFields).every(v => v === null);
}
return JSON.stringify(inputCustomFields) === JSON.stringify(existingCustomFields);
}

private async getOrdersAndItemsFromLines(
ctx: RequestContext,
orderLinesInput: OrderLineInput[],
Expand Down

0 comments on commit ef99c22

Please sign in to comment.