diff --git a/fixtures/checkout-gift-card-remove-fixture.js b/fixtures/checkout-gift-card-remove-fixture.js new file mode 100644 index 000000000..e9eac9475 --- /dev/null +++ b/fixtures/checkout-gift-card-remove-fixture.js @@ -0,0 +1,91 @@ +export default { + "data": { + "checkoutGiftCardRemoveV2": { + "checkoutUserErrors": [], + "userErrors": [], + "checkout": { + "id": "Z2lkOi8vc2hvcGlmeS9DaGVja291dC9lM2JkNzFmNzI0OGM4MDZmMzM3MjVhNTNlMzM5MzFlZj9rZXk9NDcwOTJlNDQ4NTI5MDY4ZDFiZTUyZTUwNTE2MDNhZjg=", + "appliedGiftCards": [], + "createdAt": "2017-03-17T16:00:40Z", + "updatedAt": "2017-03-17T16:00:40Z", + "requiresShipping": true, + "shippingLine": null, + "order": null, + "orderStatusUrl": null, + "taxExempt": false, + "taxesIncluded": false, + "currencyCode": "CAD", + "totalPrice": "80.28", + "lineItemsSubtotalPrice": { + "amount": "74.99", + "currencyCode": "CAD" + }, + "subtotalPrice": "67.50", + "totalTax": "8.78", + "paymentDue": "80.28", + "taxExempt": false, + "taxesIncluded": false, + "completedAt": null, + "shippingAddress": { + "address1": "123 Cat Road", + "address2": null, + "city": "Cat Land", + "company": "Catmart", + "country": "Canada", + "firstName": "Meow", + "formatted": [ + "Catmart", + "123 Cat Road", + "Cat Land ON M3O 0W1", + "Canada" + ], + "lastName": "Meowington", + "latitude": null, + "longitude": null, + "phone": "4161234566", + "province": "Ontario", + "zip": "M3O 0W1", + "name": "Meow Meowington", + "countryCode": "CA", + "provinceCode": "ON", + "id": "291dC9lM2JkNzHJnnf8a89njNJNKAhu1gn7lMzM5MzFlZj9rZXk9NDcwOTJ==" + }, + "lineItems": { + "pageInfo": { + "hasNextPage": false, + "hasPreviousPage": false + }, + "edges": [ + { + "cursor": "eyJsYXN0X2lkIjoiZDUyZWU5ZTEwYmQxMWE0NDlkNmQzMWNkMzBhMGFjNzMifQ==", + "node": { + "title": "Intelligent Granite Table", + "variant": { + "id": "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8yOTEwNjA2NDU4NA==", + "price": "74.99" + }, + "quantity": 5, + "customAttributes": [], + "discountAllocations": [ + { + "allocatedAmount": { + "amount": "7.49", + "currencyCode": "CAD" + }, + "discountApplication": { + "targetSelection": "ALL", + "allocationMethod": "ACROSS", + "targetType": "LINE_ITEM", + "code": "TENPERCENTOFF", + "applicable": true + } + } + ] + } + } + ] + } + } + } + } +}; diff --git a/src/checkout-resource.js b/src/checkout-resource.js index a81838562..e5c53b269 100644 --- a/src/checkout-resource.js +++ b/src/checkout-resource.js @@ -13,6 +13,7 @@ import checkoutAttributesUpdateV2Mutation from './graphql/checkoutAttributesUpda import checkoutDiscountCodeApplyV2Mutation from './graphql/checkoutDiscountCodeApplyV2Mutation.graphql'; import checkoutDiscountCodeRemoveMutation from './graphql/checkoutDiscountCodeRemoveMutation.graphql'; import checkoutGiftCardsAppendMutation from './graphql/checkoutGiftCardsAppendMutation.graphql'; +import checkoutGiftCardRemoveV2Mutation from './graphql/checkoutGiftCardRemoveV2Mutation.graphql'; import checkoutEmailUpdateV2Mutation from './graphql/checkoutEmailUpdateV2Mutation.graphql'; import checkoutShippingAddressUpdateV2Mutation from './graphql/checkoutShippingAddressUpdateV2Mutation.graphql'; @@ -203,6 +204,27 @@ class CheckoutResource extends Resource { .then(handleCheckoutMutation('checkoutGiftCardsAppend', this.graphQLClient)); } + /** + * Remove a gift card from an existing checkout + * + * @example + * const checkoutId = 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC9kMTZmM2EzMDM4Yjc4N='; + * const giftCardId = 'Z2lkOi8vc2hvcGlmeS9BcHBsaWVkR2lmdENhcmQvNDI4NTQ1ODAzMTI='; + * + * client.checkout.removeGiftCard(checkoutId, appliedGiftCardId).then((checkout) => { + * // Do something with the updated checkout + * }); + * + * @param {String} checkoutId The ID of the checkout to add gift cards to. + * @param {String} giftCardId The gift card id to remove from the checkout. + * @return {Promise|GraphModel} A promise resolving with the updated checkout. + */ + removeGiftCard(checkoutId, appliedGiftCardId) { + return this.graphQLClient + .send(checkoutGiftCardRemoveV2Mutation, {checkoutId, appliedGiftCardId}) + .then(handleCheckoutMutation('checkoutGiftCardRemoveV2', this.graphQLClient)); + } + /** * Removes line items from an existing checkout. * diff --git a/src/graphql/checkoutGiftCardRemoveV2Mutation.graphql b/src/graphql/checkoutGiftCardRemoveV2Mutation.graphql new file mode 100644 index 000000000..ce9c398fc --- /dev/null +++ b/src/graphql/checkoutGiftCardRemoveV2Mutation.graphql @@ -0,0 +1,13 @@ +mutation checkoutGiftCardRemoveV2($appliedGiftCardId: ID!, $checkoutId: ID!) { + checkoutGiftCardRemoveV2(appliedGiftCardId: $appliedGiftCardId, checkoutId: $checkoutId) { + userErrors { + ...UserErrorFragment + } + checkoutUserErrors { + ...CheckoutUserErrorFragment + } + checkout { + ...CheckoutFragment + } + } +} diff --git a/test/client-checkout-integration-test.js b/test/client-checkout-integration-test.js index 629802184..5fadaf472 100644 --- a/test/client-checkout-integration-test.js +++ b/test/client-checkout-integration-test.js @@ -24,6 +24,7 @@ import checkoutUpdateEmailV2WithUserErrorsFixture from '../fixtures/checkout-upd import checkoutDiscountCodeApplyV2Fixture from '../fixtures/checkout-discount-code-apply-fixture'; import checkoutDiscountCodeRemoveFixture from '../fixtures/checkout-discount-code-remove-fixture'; import checkoutGiftCardsAppendFixture from '../fixtures/checkout-gift-cards-apply-fixture'; +import checkoutGiftCardRemoveV2Fixture from '../fixtures/checkout-gift-card-remove-fixture'; import checkoutShippingAddressUpdateV2Fixture from '../fixtures/checkout-shipping-address-update-v2-fixture'; import checkoutShippingAdddressUpdateV2WithUserErrorsFixture from '../fixtures/checkout-shipping-address-update-v2-with-user-errors-fixture'; @@ -385,6 +386,52 @@ suite('client-checkout-integration-test', () => { }); }); + test('it resolves with a checkout on Client.checkout#removeGiftCard', () => { + const checkoutId = checkoutGiftCardRemoveV2Fixture.data.checkoutGiftCardRemoveV2.checkout.id; + const appliedGiftCardId = 'Z2lkOi8vc2hvcGlmeS9BcHBsaWVkR2lmdENhcmQvNDI4NTQ1ODAzMTI='; + + fetchMockPostOnce(fetchMock, apiUrl, checkoutGiftCardRemoveV2Fixture); + + return client.checkout.removeGiftCard(checkoutId, appliedGiftCardId).then((checkout) => { + assert.equal(checkout.id, checkoutId); + assert.ok(fetchMock.done()); + }); + }); + + test('it resolves with checkoutUserErrors on Client.checkout#removeGiftCard with a code not present', () => { + const checkoutGiftCardsRemoveV2WithCheckoutUserErrorsFixture = { + data: { + checkoutGiftCardRemoveV2: { + checkoutUserErrors: [ + { + message: 'Applied Gift Card not found', + field: null, + code: 'GIFT_CARD_NOT_FOUND' + } + ], + userErrors: [ + { + message: 'Applied Gift Card not found', + field: null + } + ], + checkout: null + } + } + }; + + fetchMockPostOnce(fetchMock, apiUrl, checkoutGiftCardsRemoveV2WithCheckoutUserErrorsFixture); + + const checkoutId = checkoutGiftCardRemoveV2Fixture.data.checkoutGiftCardRemoveV2.checkout.id; + const appliedGiftCardId = 'Z2lkOi8vc2hvcGlmeS9BcHBsaWVkR2lmdENhcmQvNDI4NTQ1ODAzMTI='; + + return client.checkout.removeGiftCard(checkoutId, appliedGiftCardId).then(() => { + assert.ok(false, 'Promise should not resolve'); + }).catch((error) => { + assert.equal(error.message, '[{"message":"Applied Gift Card not found","field":null,"code":"GIFT_CARD_NOT_FOUND"}]'); + }); + }); + test('it resolves with a checkout on Client.checkout#updateShippingAddress', () => { const {id: checkoutId} = checkoutShippingAddressUpdateV2Fixture.data.checkoutShippingAddressUpdateV2.checkout; const {