diff --git a/src/components/cart.js b/src/components/cart.js
index bb5be0a9..4adc0a0d 100644
--- a/src/components/cart.js
+++ b/src/components/cart.js
@@ -116,6 +116,7 @@ export default class Cart extends Component {
data.classes = this.classes;
data.text = this.config.lineItem.text;
data.lineItemImage = this.imageForLineItem(data);
+ data.lineItemImageAltText = this.imageAltTextForLineItem(data);
data.variantTitle = data.variant.title === 'Default Title' ? '' : data.variant.title;
return acc + this.childTemplate.render({data}, (output) => `
${output}`);
}, '');
@@ -215,6 +216,14 @@ export default class Cart extends Component {
}
}
+ imageAltTextForLineItem(lineItem) {
+ if (lineItem.variant.image) {
+ return lineItem.variant.image.altText || lineItem.title;
+ } else {
+ return null;
+ }
+ }
+
/**
* sets model to null and removes checkout from localStorage
* @return {Promise} promise resolving to the cart model
diff --git a/src/templates/line-item.js b/src/templates/line-item.js
index b66f341d..0dfb2966 100644
--- a/src/templates/line-item.js
+++ b/src/templates/line-item.js
@@ -1,5 +1,5 @@
const lineItemTemplates = {
- image: '',
+ image: '',
variantTitle: '{{data.variantTitle}}
',
title: '{{data.title}}',
diff --git a/test/unit/cart/cart.js b/test/unit/cart/cart.js
index 3774909f..d02af3a1 100644
--- a/test/unit/cart/cart.js
+++ b/test/unit/cart/cart.js
@@ -130,13 +130,17 @@ describe('Cart class', () => {
describe('get lineItemsHtml', () => {
const variantAmount = '5.00';
let formatMoneySpy;
+ let renderSpy;
+
beforeEach(() => {
formatMoneySpy = sinon.spy(formatMoney, 'default');
+ renderSpy = sinon.spy(cart.childTemplate, 'render');
});
afterEach(() => {
formatMoneySpy.restore();
+ renderSpy.restore();
});
it('calls render and returns an html string', () => {
@@ -157,7 +161,6 @@ describe('Cart class', () => {
discountAllocations: [],
}];
- const renderSpy = sinon.spy(cart.childTemplate, 'render');
const cartLineItemsHtml = cart.lineItemsHtml;
assert.include(cartLineItemsHtml, 'data-line-item-id="123"');
assert.match(cartLineItemsHtml, /[\s\S]*<\/li>/);
@@ -188,6 +191,69 @@ describe('Cart class', () => {
assert.include(cartLineItemsHtml, `${quantityIncrementAccessibilityLabel}`);
});
+ describe('Line item image', () => {
+ beforeEach(() => {
+ cart.lineItemCache = [{
+ id: 123,
+ title: 'test',
+ variantTitle: 'test2',
+ quantity: 1,
+ variant: {
+ image: {
+ src: 'cdn.shopify.com/image.jpg',
+ },
+ priceV2: {
+ amount: '5.00',
+ currencyCode: 'CAD',
+ },
+ },
+ discountAllocations: [],
+ }];
+ });
+
+ it('renders the child template with a line item image', () => {
+ const mockLineItemImage = 'mock-image-src.com';
+ const imageForLineItemStub = sinon.stub(cart, 'imageForLineItem').returns(mockLineItemImage);
+
+ const cartLineItemsHtml = cart.lineItemsHtml;
+ const renderData = renderSpy.getCall(0).args[0].data;
+
+ assert.calledOnce(imageForLineItemStub);
+ assert.equal(renderData.lineItemImage, mockLineItemImage);
+ assert.include(cartLineItemsHtml, `style="background-image: url(${mockLineItemImage})"`);
+
+ imageForLineItemStub.restore();
+ });
+
+ it('renders the child template line item image with a role and aria-label if alt text is not null', () => {
+ const mockLineItemImageAltText = 'alt text';
+ const imageAltTextForLineItemStub = sinon.stub(cart, 'imageAltTextForLineItem').returns(mockLineItemImageAltText);
+
+ const cartLineItemsHtml = cart.lineItemsHtml;
+ const renderData = renderSpy.getCall(0).args[0].data;
+
+ assert.calledOnce(imageAltTextForLineItemStub);
+ assert.equal(renderData.lineItemImageAltText, mockLineItemImageAltText);
+ assert.include(cartLineItemsHtml, `role="img" aria-label="${mockLineItemImageAltText}"`);
+
+ imageAltTextForLineItemStub.restore();
+ });
+
+ it('renders the child template line item image without a role or aria-label if alt text is null', () => {
+ const mockLineItemImageAltText = null;
+ const imageAltTextForLineItemStub = sinon.stub(cart, 'imageAltTextForLineItem').returns(mockLineItemImageAltText);
+
+ const cartLineItemsHtml = cart.lineItemsHtml;
+ const renderData = renderSpy.getCall(0).args[0].data;
+
+ assert.calledOnce(imageAltTextForLineItemStub);
+ assert.equal(renderData.lineItemImageAltText, mockLineItemImageAltText);
+ assert.notInclude(cartLineItemsHtml, 'role="img" aria-label');
+
+ imageAltTextForLineItemStub.restore();
+ });
+ });
+
describe('price without discounts', () => {
beforeEach(() => {
cart.childTemplate.contents.price = true;
@@ -501,6 +567,49 @@ describe('Cart class', () => {
});
});
+ describe('imageAltTextForLineItem', () => {
+ it('returns null if the line item variant image does not exist', () => {
+ const lineItem = {
+ variant: {
+ id: 123,
+ },
+ };
+ const altText = cart.imageAltTextForLineItem(lineItem);
+
+ assert.equal(altText, null);
+ });
+
+ it('returns the line item variant image alt text if it exists', () => {
+ const lineItem = {
+ title: 'title',
+ variant: {
+ id: 123,
+ image: {
+ altText: 'image alt text',
+ },
+ },
+ };
+ const altText = cart.imageAltTextForLineItem(lineItem);
+
+ assert.equal(altText, lineItem.variant.image.altText);
+ });
+
+ it('returns the line item title if the variant image alt text does not exist', () => {
+ const lineItem = {
+ title: 'title',
+ variant: {
+ id: 123,
+ image: {
+ src: 'cdn.shopify.com/variant_image.jpg',
+ },
+ },
+ };
+ const altText = cart.imageAltTextForLineItem(lineItem);
+
+ assert.equal(altText, lineItem.title);
+ });
+ });
+
describe('fetchData()', () => {
it('resolves to null if key does not exist in localStorage', () => {
localStorage.removeItem(cart.localStorageCheckoutKey);