Skip to content

Commit

Permalink
resource-ify checkout
Browse files Browse the repository at this point in the history
  • Loading branch information
Mina Smart committed Nov 30, 2017
1 parent 14871c5 commit f1c892b
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 145 deletions.
139 changes: 139 additions & 0 deletions src/checkout-resource.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import Resource from './resource';
import defaultResolver from './default-resolver';
import handleCheckoutMutation from './handle-checkout-mutation';

// GraphQL
import checkoutNodeQuery from './graphql/checkoutNodeQuery.graphql';
import checkoutCreateMutation from './graphql/checkoutCreateMutation.graphql';
import checkoutLineItemsAddMutation from './graphql/checkoutLineItemsAddMutation.graphql';
import checkoutLineItemsRemoveMutation from './graphql/checkoutLineItemsRemoveMutation.graphql';
import checkoutLineItemsUpdateMutation from './graphql/checkoutLineItemsUpdateMutation.graphql';

export default class CheckoutResource extends Resource {

/**
* Fetches a checkout by ID.
*
* @example
* client.fetchCheckout('FlZj9rZXlN5MDY4ZDFiZTUyZTUwNTE2MDNhZjg=').then((checkout) => {
* // Do something with the checkout
* });
*
* @param {String} id The id of the checkout to fetch.
* @param {Client.Queries.checkoutNodeQuery} [query] Callback function to specify fields to query on the checkout.
* @return {Promise|GraphModel} A promise resolving with a `GraphModel` of the checkout.
*/
fetch(id) {
return this.graphQLClient
.send(checkoutNodeQuery, {id})
.then(defaultResolver('node'))
.then((checkout) => {
return this.graphQLClient.fetchAllPages(checkout.lineItems, {pageSize: 250}).then((lineItems) => {
checkout.attrs.lineItems = lineItems;

return checkout;
});
});
}

/**
* Creates a checkout.
*
* @example
* const input = {
* lineItems: [
* {variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8yOTEwNjAyMjc5Mg==', quantity: 5}
* ]
* };
*
* client.createCheckout(input).then((checkout) => {
* // Do something with the newly created checkout
* });
*
* @param {Object} [input] An input object containing zero or more of:
* @param {String} [input.email] An email connected to the checkout.
* @param {Object[]} [input.lineItems] A list of line items in the checkout. See the {@link https://help.shopify.com/api/storefront-api/reference/input_object/checkoutlineiteminput|Storefront API reference} for valid input fields for each line item.
* @param {Object} [input.shippingAddress] A shipping address. See the {@link https://help.shopify.com/api/storefront-api/reference/input_object/mailingaddressinput|Storefront API reference} for valid input fields.
* @param {String} [input.note] A note for the checkout.
* @param {Object[]} [input.customAttributes] A list of custom attributes for the checkout. See the {@link https://help.shopify.com/api/storefront-api/reference/input_object/attributeinput|Storefront API reference} for valid input fields.
* @param {Client.Queries.checkoutQuery} [query] Callback function to specify fields to query on the checkout returned.
* @return {Promise|GraphModel} A promise resolving with the created checkout.
*/
create(input = {}) {
return this.graphQLClient
.send(checkoutCreateMutation, {input})
.then(handleCheckoutMutation('checkoutCreate', this.graphQLClient));
}

/**
* Adds line items to an existing checkout.
*
* @example
* const checkoutId = 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC9kMTZmM2EzMDM4Yjc4N=';
* const lineItems = [{variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8yOTEwNjAyMjc5Mg==', quantity: 5}];
*
* client.addLineItems(checkoutId, lineItems).then((checkout) => {
* // Do something with the updated checkout
* });
*
* @param {String} checkoutId The ID of the checkout to add line items to.
* @param {Object[]} lineItems A list of line items to add to the checkout. See the {@link https://help.shopify.com/api/storefront-api/reference/input_object/checkoutlineiteminput|Storefront API reference} for valid input fields for each line item.
* @param {Client.Queries.checkoutQuery} [query] Callback function to specify fields to query on the checkout returned.
* @return {Promise|GraphModel} A promise resolving with the updated checkout.
*/
addLineItems(checkoutId, lineItems) {
return this.graphQLClient
.send(checkoutLineItemsAddMutation, {checkoutId, lineItems})
.then(handleCheckoutMutation('checkoutLineItemsAdd', this.graphQLClient));
}

/**
* Removes line items from an existing checkout.
*
* @example
* const checkoutId = 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC9kMTZmM2EzMDM4Yjc4N=';
* const lineItemIds = ['TViZGE5Y2U1ZDFhY2FiMmM2YT9rZXk9NTc2YjBhODcwNWIxYzg0YjE5ZjRmZGQ5NjczNGVkZGU='];
*
* client.removeLineItems(checkoutId, lineItemIds).then((checkout) => {
* // Do something with the updated checkout
* });
*
* @param {String} checkoutId The ID of the checkout to remove line items from.
* @param {String[]} lineItemIds A list of the ids of line items to remove from the checkout.
* @param {Client.Queries.checkoutQuery} [query] Callback function to specify fields to query on the checkout returned.
* @return {Promise|GraphModel} A promise resolving with the updated checkout.
*/
removeLineItems(checkoutId, lineItemIds) {
return this.graphQLClient
.send(checkoutLineItemsRemoveMutation, {checkoutId, lineItemIds})
.then(handleCheckoutMutation('checkoutLineItemsRemove', this.graphQLClient));
}

/**
* Updates line items on an existing checkout.
*
* @example
* const checkoutId = 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC9kMTZmM2EzMDM4Yjc4N=';
* const lineItems = [
* {
* id: 'TViZGE5Y2U1ZDFhY2FiMmM2YT9rZXk9NTc2YjBhODcwNWIxYzg0YjE5ZjRmZGQ5NjczNGVkZGU=',
* quantity: 5,
* variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8yOTEwNjAyMjc5Mg=='
* }
* ];
*
* client.updateLineItems(checkoutId, lineItems).then(checkout => {
* // Do something with the updated checkout
* });
*
* @param {String} checkoutId The ID of the checkout to update a line item on.
* @param {Object[]} lineItems A list of line item information to update. See the {@link https://help.shopify.com/api/storefront-api/reference/input_object/checkoutlineitemupdateinput|Storefront API reference} for valid input fields for each line item.
* @param {Client.Queries.checkoutQuery} [query] Callback function to specify fields to query on the checkout returned.
* @return {Promise|GraphModel} A promise resolving with the updated checkout.
*/
updateLineItems(checkoutId, lineItems) {
return this.graphQLClient
.send(checkoutLineItemsUpdateMutation, {checkoutId, lineItems})
.then(handleCheckoutMutation('checkoutLineItemsUpdate', this.graphQLClient));
}
}
135 changes: 2 additions & 133 deletions src/client.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import GraphQLJSClient from './graphql-client';
import Config from './config';
import handleCheckoutMutation from './handle-checkout-mutation';
import productHelpers from './product-helpers';
import imageHelpers from './image-helpers';
import defaultResolver from './default-resolver';
import ProductResource from './product-resource';
import CollectionResource from './collection-resource';
import ShopResource from './shop-resource';
import CheckoutResource from './checkout-resource';
import {version} from '../package.json';

// GraphQL
import types from '../schema.json';
import checkoutNodeQuery from './graphql/checkoutNodeQuery.graphql';
import checkoutCreateMutation from './graphql/checkoutCreateMutation.graphql';
import checkoutLineItemsAddMutation from './graphql/checkoutLineItemsAddMutation.graphql';
import checkoutLineItemsRemoveMutation from './graphql/checkoutLineItemsRemoveMutation.graphql';
import checkoutLineItemsUpdateMutation from './graphql/checkoutLineItemsUpdateMutation.graphql';

/**
* The JS Buy SDK Client.
Expand Down Expand Up @@ -73,132 +67,7 @@ class Client {
this.product = new ProductResource(this.graphQLClient, productHelpers);
this.collection = new CollectionResource(this.graphQLClient);
this.shop = new ShopResource(this.graphQLClient);
}

/**
* Fetches a checkout by ID.
*
* @example
* client.fetchCheckout('FlZj9rZXlN5MDY4ZDFiZTUyZTUwNTE2MDNhZjg=').then((checkout) => {
* // Do something with the checkout
* });
*
* @param {String} id The id of the checkout to fetch.
* @param {Client.Queries.checkoutNodeQuery} [query] Callback function to specify fields to query on the checkout.
* @return {Promise|GraphModel} A promise resolving with a `GraphModel` of the checkout.
*/
fetchCheckout(id) {
return this.graphQLClient
.send(checkoutNodeQuery, {id})
.then(defaultResolver('node'))
.then((checkout) => {
return this.graphQLClient.fetchAllPages(checkout.lineItems, {pageSize: 250}).then((lineItems) => {
checkout.attrs.lineItems = lineItems;

return checkout;
});
});
}

/**
* Creates a checkout.
*
* @example
* const input = {
* lineItems: [
* {variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8yOTEwNjAyMjc5Mg==', quantity: 5}
* ]
* };
*
* client.createCheckout(input).then((checkout) => {
* // Do something with the newly created checkout
* });
*
* @param {Object} [input] An input object containing zero or more of:
* @param {String} [input.email] An email connected to the checkout.
* @param {Object[]} [input.lineItems] A list of line items in the checkout. See the {@link https://help.shopify.com/api/storefront-api/reference/input_object/checkoutlineiteminput|Storefront API reference} for valid input fields for each line item.
* @param {Object} [input.shippingAddress] A shipping address. See the {@link https://help.shopify.com/api/storefront-api/reference/input_object/mailingaddressinput|Storefront API reference} for valid input fields.
* @param {String} [input.note] A note for the checkout.
* @param {Object[]} [input.customAttributes] A list of custom attributes for the checkout. See the {@link https://help.shopify.com/api/storefront-api/reference/input_object/attributeinput|Storefront API reference} for valid input fields.
* @param {Client.Queries.checkoutQuery} [query] Callback function to specify fields to query on the checkout returned.
* @return {Promise|GraphModel} A promise resolving with the created checkout.
*/
createCheckout(input = {}) {
return this.graphQLClient
.send(checkoutCreateMutation, {input})
.then(handleCheckoutMutation('checkoutCreate', this.graphQLClient));
}

/**
* Adds line items to an existing checkout.
*
* @example
* const checkoutId = 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC9kMTZmM2EzMDM4Yjc4N=';
* const lineItems = [{variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8yOTEwNjAyMjc5Mg==', quantity: 5}];
*
* client.addLineItems(checkoutId, lineItems).then((checkout) => {
* // Do something with the updated checkout
* });
*
* @param {String} checkoutId The ID of the checkout to add line items to.
* @param {Object[]} lineItems A list of line items to add to the checkout. See the {@link https://help.shopify.com/api/storefront-api/reference/input_object/checkoutlineiteminput|Storefront API reference} for valid input fields for each line item.
* @param {Client.Queries.checkoutQuery} [query] Callback function to specify fields to query on the checkout returned.
* @return {Promise|GraphModel} A promise resolving with the updated checkout.
*/
addLineItems(checkoutId, lineItems) {
return this.graphQLClient
.send(checkoutLineItemsAddMutation, {checkoutId, lineItems})
.then(handleCheckoutMutation('checkoutLineItemsAdd', this.graphQLClient));
}

/**
* Removes line items from an existing checkout.
*
* @example
* const checkoutId = 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC9kMTZmM2EzMDM4Yjc4N=';
* const lineItemIds = ['TViZGE5Y2U1ZDFhY2FiMmM2YT9rZXk9NTc2YjBhODcwNWIxYzg0YjE5ZjRmZGQ5NjczNGVkZGU='];
*
* client.removeLineItems(checkoutId, lineItemIds).then((checkout) => {
* // Do something with the updated checkout
* });
*
* @param {String} checkoutId The ID of the checkout to remove line items from.
* @param {String[]} lineItemIds A list of the ids of line items to remove from the checkout.
* @param {Client.Queries.checkoutQuery} [query] Callback function to specify fields to query on the checkout returned.
* @return {Promise|GraphModel} A promise resolving with the updated checkout.
*/
removeLineItems(checkoutId, lineItemIds) {
return this.graphQLClient
.send(checkoutLineItemsRemoveMutation, {checkoutId, lineItemIds})
.then(handleCheckoutMutation('checkoutLineItemsRemove', this.graphQLClient));
}

/**
* Updates line items on an existing checkout.
*
* @example
* const checkoutId = 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC9kMTZmM2EzMDM4Yjc4N=';
* const lineItems = [
* {
* id: 'TViZGE5Y2U1ZDFhY2FiMmM2YT9rZXk9NTc2YjBhODcwNWIxYzg0YjE5ZjRmZGQ5NjczNGVkZGU=',
* quantity: 5,
* variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8yOTEwNjAyMjc5Mg=='
* }
* ];
*
* client.updateLineItems(checkoutId, lineItems).then(checkout => {
* // Do something with the updated checkout
* });
*
* @param {String} checkoutId The ID of the checkout to update a line item on.
* @param {Object[]} lineItems A list of line item information to update. See the {@link https://help.shopify.com/api/storefront-api/reference/input_object/checkoutlineitemupdateinput|Storefront API reference} for valid input fields for each line item.
* @param {Client.Queries.checkoutQuery} [query] Callback function to specify fields to query on the checkout returned.
* @return {Promise|GraphModel} A promise resolving with the updated checkout.
*/
updateLineItems(checkoutId, lineItems) {
return this.graphQLClient
.send(checkoutLineItemsUpdateMutation, {checkoutId, lineItems})
.then(handleCheckoutMutation('checkoutLineItemsUpdate', this.graphQLClient));
this.checkout = new CheckoutResource(this.graphQLClient);
}
}

Expand Down
24 changes: 12 additions & 12 deletions test/client-checkout-integration-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@ suite('client-checkout-integration-test', () => {
fetchMock.restore();
});

test('it resolves with a checkout on Client#fetchCheckout', () => {
test('it resolves with a checkout on Client.checkout#fetch', () => {
fetchMock.postOnce(apiUrl, checkoutFixture);

const checkoutId = checkoutFixture.data.node.id;

return client.fetchCheckout(checkoutId).then((checkout) => {
return client.checkout.fetch(checkoutId).then((checkout) => {
assert.equal(checkout.id, checkoutId);
assert.ok(fetchMock.done());
});
});

test('it resolves with a checkout on Client#createCheckout', () => {
test('it resolves with a checkout on Client.checkout#create', () => {
const input = {
lineItems: [
{
Expand All @@ -54,13 +54,13 @@ suite('client-checkout-integration-test', () => {

fetchMock.postOnce(apiUrl, checkoutCreateFixture);

return client.createCheckout(input).then((checkout) => {
return client.checkout.create(input).then((checkout) => {
assert.equal(checkout.id, checkoutCreateFixture.data.checkoutCreate.checkout.id);
assert.ok(fetchMock.done());
});
});

test('it resolves with a checkout on Client#addLineItems', () => {
test('it resolves with a checkout on Client.checkout#addLineItems', () => {
const checkoutId = checkoutLineItemsAddFixture.data.checkoutLineItemsAdd.checkout.id;
const lineItems = [
{variantId: 'id1', quantity: 5},
Expand All @@ -69,13 +69,13 @@ suite('client-checkout-integration-test', () => {

fetchMock.postOnce(apiUrl, checkoutLineItemsAddFixture);

return client.addLineItems(checkoutId, lineItems).then((checkout) => {
return client.checkout.addLineItems(checkoutId, lineItems).then((checkout) => {
assert.equal(checkout.id, checkoutId);
assert.ok(fetchMock.done());
});
});

test('it resolves with a checkout on Client#updateLineItems', () => {
test('it resolves with a checkout on Client.checkout#updateLineItems', () => {
fetchMock.postOnce(apiUrl, checkoutLineItemsUpdateFixture);

const checkoutId = checkoutLineItemsUpdateFixture.data.checkoutLineItemsUpdate.checkout.id;
Expand All @@ -87,18 +87,18 @@ suite('client-checkout-integration-test', () => {
}
];

return client.updateLineItems(checkoutId, lineItems).then((checkout) => {
return client.checkout.updateLineItems(checkoutId, lineItems).then((checkout) => {
assert.equal(checkout.id, checkoutId);
assert.ok(fetchMock.done());
});
});

test('it resolves with a checkout on Client#removeLineItems', () => {
test('it resolves with a checkout on Client.checkout#removeLineItems', () => {
fetchMock.postOnce(apiUrl, checkoutLineItemsRemoveFixture);

const checkoutId = checkoutLineItemsRemoveFixture.data.checkoutLineItemsRemove.checkout.id;

return client.removeLineItems(checkoutId, ['line-item-id']).then((checkout) => {
return client.checkout.removeLineItems(checkoutId, ['line-item-id']).then((checkout) => {
assert.equal(checkout.id, checkoutId);
assert.ok(fetchMock.done());
});
Expand All @@ -117,7 +117,7 @@ suite('client-checkout-integration-test', () => {
.postOnce(apiUrl, secondPageLineItemsFixture)
.postOnce(apiUrl, thirdPageLineItemsFixture);

return client.createCheckout(input).then(() => {
return client.checkout.create(input).then(() => {
assert.ok(fetchMock.done());
});
});
Expand Down Expand Up @@ -149,7 +149,7 @@ suite('client-checkout-integration-test', () => {

fetchMock.postOnce(apiUrl, checkoutCreateWithUserErrorsFixture);

return client.createCheckout(input).then(() => {
return client.checkout.create(input).then(() => {
assert.ok(false, 'Promise should not resolve');
}).catch((error) => {
assert.equal(error.message, '[{"message":"Variant is invalid","field":["lineItems","0","variantId"]}]');
Expand Down

0 comments on commit f1c892b

Please sign in to comment.