diff --git a/fixtures/checkout-shipping-line-update-fixture.js b/fixtures/checkout-shipping-line-update-fixture.js new file mode 100644 index 000000000..bf632fb1d --- /dev/null +++ b/fixtures/checkout-shipping-line-update-fixture.js @@ -0,0 +1,81 @@ +export default { + "data": { + "checkoutShippingLineUpdate": { + "userErrors": [], + "checkoutUserErrors": [], + "checkout": { + "id": "Z2lkOi8vc2hvcGlmeS9DaGVja291dC9lM2JkNzFmNzI0OGM4MDZmMzM3MjVhNTNlMzM5MzFlZj9rZXk9NDcwOTJlNDQ4NTI5MDY4ZDFiZTUyZTUwNTE2MDNhZjg=", + "createdAt": "2017-03-17T16:00:40Z", + "updatedAt": "2017-03-17T16:00:40Z", + "requiresShipping": true, + "shippingLine": { + "handle": "standard-shipping", + "priceV2": { + "amount": "0.00", + "currencyCode": "CAD" + }, + "title": "Standard shipping" + }, + "order": null, + "orderStatusUrl": null, + "taxExempt": false, + "taxesIncluded": false, + "currencyCode": "CAD", + "lineItemsSubtotalPrice": { + "amount": "374.95", + "currencyCode": "CAD" + }, + "totalPrice": "80.28", + "subtotalPrice": "67.50", + "totalTax": "8.78", + "paymentDue": "80.28", + "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": "Z2lkOi8vc2hvcGlmeS9QcmdfnAU8nakdWMnAbh890hyOTEwNjA2NDU4NA==" + }, + "lineItems": { + "pageInfo": { + "hasNextPage": false, + "hasPreviousPage": false + }, + "edges": [ + { + "cursor": "eyJsYXN0X2lkIjoiZDUyZWU5ZTEwYmQxMWE0NDlkNmQzMWNkMzBhMGFjNzMifQ==", + "node": { + "title": "Intelligent Granite Table", + "variant": { + "id": "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8yOTEwNjA2NDU4NA==", + "price": "74.99" + }, + "quantity": 5, + "customAttributes": [], + "discountAllocations": [] + } + } + ] + } + } + } + } +}; diff --git a/src/checkout-resource.js b/src/checkout-resource.js index 878dd5ab0..a9976aa59 100644 --- a/src/checkout-resource.js +++ b/src/checkout-resource.js @@ -9,6 +9,7 @@ import checkoutLineItemsAddMutation from './graphql/checkoutLineItemsAddMutation import checkoutLineItemsRemoveMutation from './graphql/checkoutLineItemsRemoveMutation.graphql'; import checkoutLineItemsReplaceMutation from './graphql/checkoutLineItemsReplaceMutation.graphql'; import checkoutLineItemsUpdateMutation from './graphql/checkoutLineItemsUpdateMutation.graphql'; +import checkoutShippingLineUpdateMutation from './graphql/checkoutShippingLineUpdateMutation.graphql'; import checkoutAttributesUpdateV2Mutation from './graphql/checkoutAttributesUpdateV2Mutation.graphql'; import checkoutDiscountCodeApplyV2Mutation from './graphql/checkoutDiscountCodeApplyV2Mutation.graphql'; import checkoutDiscountCodeRemoveMutation from './graphql/checkoutDiscountCodeRemoveMutation.graphql'; @@ -326,6 +327,27 @@ class CheckoutResource extends Resource { .send(checkoutShippingAddressUpdateV2Mutation, {checkoutId, shippingAddress}) .then(handleCheckoutMutation('checkoutShippingAddressUpdateV2', this.graphQLClient)); } + + /** + * Updates shipping line on an existing checkout . + * + * @example + * const checkoutId = 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC9kMTZmM2EzMDM4Yjc4N='; + * const shippingRateHandle = 'placeholder'; + * + * client.checkout.updateShippingLine(checkoutId, shippingRateHandle).then(checkout => { + * // Do something with the updated checkout + * }); + * + * @param {String} checkoutId The ID of the checkout to update shipping address. + * @param {Object} shippingRateHandle A unique identifier to a Checkout’s shipping provider, price, and title combination, enabling the customer to select the availableShippingRates. + * @return {Promise|GraphModel} A promise resolving with the updated checkout. + */ + updateShippingLine(checkoutId, shippingRateHandle) { + return this.graphQLClient + .send(checkoutShippingLineUpdateMutation, {checkoutId, shippingRateHandle}) + .then(handleCheckoutMutation('checkoutShippingLineUpdate', this.graphQLClient)); + } } export default CheckoutResource; diff --git a/src/graphql/checkoutShippingLineUpdateMutation.graphql b/src/graphql/checkoutShippingLineUpdateMutation.graphql new file mode 100644 index 000000000..3bb3fd86b --- /dev/null +++ b/src/graphql/checkoutShippingLineUpdateMutation.graphql @@ -0,0 +1,13 @@ +mutation checkoutShippingLineUpdate($checkoutId: ID!, $shippingRateHandle: String!) { + checkoutShippingLineUpdate(checkoutId: $checkoutId, shippingRateHandle: $shippingRateHandle) { + userErrors { + ...UserErrorFragment + } + checkoutUserErrors { + ...CheckoutUserErrorFragment + } + checkout { + ...CheckoutFragment + } + } +} diff --git a/test/client-checkout-integration-test.js b/test/client-checkout-integration-test.js index 53477c4fe..3b8cf445c 100644 --- a/test/client-checkout-integration-test.js +++ b/test/client-checkout-integration-test.js @@ -28,6 +28,7 @@ import checkoutGiftCardsAppendFixture from '../fixtures/checkout-gift-cards-appl 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'; +import checkoutShippingLineUpdateFixture from '../fixtures/checkout-shipping-line-update-fixture'; suite('client-checkout-integration-test', () => { const domain = 'client-integration-tests.myshopify.io'; @@ -484,6 +485,27 @@ suite('client-checkout-integration-test', () => { }); }); + test('it resolves with a checkout on Client.checkout#updateShippingLine', () => { + const {id: checkoutId} = checkoutShippingLineUpdateFixture.data.checkoutShippingLineUpdate.checkout; + const { + handle: shippingLineName, + priceV2: shippingLinePriceV2, + title: shippingLineTitle + } = checkoutShippingLineUpdateFixture.data.checkoutShippingLineUpdate.checkout.shippingLine; + const shippingHandle = 'standard-shipping'; + + fetchMockPostOnce(fetchMock, apiUrl, checkoutShippingLineUpdateFixture); + + return client.checkout.updateShippingLine(checkoutId, shippingHandle).then((checkout) => { + assert.equal(checkout.id, checkoutId); + assert.equal(checkout.shippingLine.handle, shippingLineName); + assert.equal(checkout.shippingLine.priceV2.amount, shippingLinePriceV2.amount); + assert.equal(checkout.shippingLine.priceV2.currencyCode, shippingLinePriceV2.currencyCode); + assert.equal(checkout.shippingLine.title, shippingLineTitle); + assert.ok(fetchMock.done()); + }); + }); + test('it fetches all paginated line items on the checkout on any checkout mutation', () => { const input = { lineItems: [