Skip to content

Commit 574d8fe

Browse files
committed
test(theme): add cartSidebar tests
1 parent 0da1899 commit 574d8fe

File tree

7 files changed

+168
-5
lines changed

7 files changed

+168
-5
lines changed

packages/theme/components/SearchResults.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
>
3737
<SfMenuItem
3838
:label="category.label"
39-
:link="localePath(th.getAgnosticCatLink(category))"
39+
:link="th.getAgnosticCatLink(category)"
4040
>
4141
<template #mobile-nav-icon>
4242
&#8203;
@@ -76,7 +76,7 @@
7676
:image="productGetters.getProductThumbnailImage(product)"
7777
:alt="productGetters.getName(product)"
7878
:title="productGetters.getName(product)"
79-
:link="localePath(`/p/${productGetters.getProductSku(product)}${productGetters.getSlug(product, product.categories[0])}`)"
79+
:link="`/p/${productGetters.getProductSku(product)}${productGetters.getSlug(product, product.categories[0])}`"
8080
:wishlist-icon="isAuthenticated ? 'heart' : ''"
8181
:is-in-wishlist-icon="isAuthenticated ? 'heart_fill' : ''"
8282
:is-in-wishlist="product.isInWishlist"
@@ -96,7 +96,7 @@
9696
:image="productGetters.getProductThumbnailImage(product)"
9797
:alt="productGetters.getName(product)"
9898
:title="productGetters.getName(product)"
99-
:link="localePath(`/p/${productGetters.getProductSku(product)}${productGetters.getSlug(product, product.categories[0])}`)"
99+
:link="`/p/${productGetters.getProductSku(product)}${productGetters.getSlug(product, product.categories[0])}`"
100100
:wishlist-icon="isAuthenticated ? 'heart' : ''"
101101
:is-in-wishlist-icon="isAuthenticated ? 'heart_fill' : ''"
102102
:is-in-wishlist="product.isInWishlist"
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import userEvent from '@testing-library/user-event';
2+
import {
3+
useExternalCheckout,
4+
useCart,
5+
useUser,
6+
} from '@vue-storefront/magento';
7+
8+
import { useUiState } from '~/composables';
9+
import {
10+
render, useCartMock, useUserMock, useUiStateMock, useEmptyCartMock,
11+
} from '~/test-utils';
12+
import CartSidebar from '~/components/CartSidebar';
13+
import stockStatusEnum from '~/enums/stockStatusEnum';
14+
15+
jest.mock('@vue-storefront/magento', () => ({
16+
...jest.requireActual('@vue-storefront/magento'),
17+
useExternalCheckout: jest.fn(() => ({ initializeCheckout: {} })),
18+
useCart: jest.fn(),
19+
useUser: jest.fn(),
20+
}));
21+
22+
jest.mock('~/composables/useUiState');
23+
24+
useUser.mockReturnValue(useUserMock());
25+
useCart.mockReturnValue(useCartMock());
26+
27+
describe('<CartSidebar>', () => {
28+
it('should be not visible by default', () => {
29+
useUiState.mockReturnValue(useUiStateMock());
30+
const { queryByText } = render(CartSidebar);
31+
expect(queryByText('My Cart')).toBeNull();
32+
});
33+
34+
describe('If the cart is empty', () => {
35+
beforeAll(() => {
36+
useCart.mockReturnValue(useEmptyCartMock());
37+
});
38+
describe('And the cart sidebar is open', () => {
39+
it('should render empty state', () => {
40+
useUiState.mockReturnValue(useUiStateMock({ isCartSidebarOpen: true }));
41+
const { queryByText } = render(CartSidebar);
42+
expect(queryByText('Your cart is empty')).toBeTruthy();
43+
});
44+
45+
it('go back button must close the cart sidebar', () => {
46+
const uiStateMock = useUiStateMock({ isCartSidebarOpen: true });
47+
useUiState.mockReturnValue(uiStateMock);
48+
const { queryByText } = render(CartSidebar);
49+
const closeSidebarBtn = queryByText('Go back shopping');
50+
expect(closeSidebarBtn).toBeTruthy();
51+
52+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
53+
userEvent.click(closeSidebarBtn);
54+
expect(uiStateMock.toggleCartSidebar.mock.calls).toHaveLength(1);
55+
});
56+
});
57+
});
58+
59+
describe('If the cart has two products', () => {
60+
beforeAll(() => {
61+
useCart.mockReturnValue(useCartMock());
62+
useUiState.mockReturnValue(useUiStateMock({ isCartSidebarOpen: true }));
63+
});
64+
65+
it('should render two Product Cards', () => {
66+
const { container } = render(CartSidebar);
67+
const productCards = container.querySelectorAll('div.sf-collected-product');
68+
expect(productCards).toHaveLength(2);
69+
});
70+
71+
it('should display proper total items value', () => {
72+
const { container } = render(CartSidebar);
73+
const totalItemsLValue = container.querySelector('div.cart-summary .sf-property__value');
74+
const totalItemsLabel = container.querySelector('div.cart-summary .sf-property__name');
75+
expect(totalItemsLabel).toHaveTextContent('Total items');
76+
expect(totalItemsLValue).toHaveTextContent(2);
77+
});
78+
79+
describe('And exactly one product is out of stock', () => {
80+
it('should display exactly one out of stock badge', () => {
81+
const { getAllByText } = render(CartSidebar);
82+
expect(getAllByText('Out of stock')).toHaveLength(1);
83+
});
84+
});
85+
});
86+
});

packages/theme/test-utils.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import { render } from '@testing-library/vue';
22

33
const $t = (text) => text;
4-
4+
const $n = (text) => text;
5+
const localePath = (path) => path;
56
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
67
const customRender = (component, options = {}, callback = null) => render(component, {
78
mocks: {
89
$t,
10+
$n,
11+
localePath,
912
$nuxt: {
1013
context: {
1114
app: {
12-
localePath: (path) => path,
15+
localePath,
1316
},
1417
},
1518
},
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import stockStatusEnum from '~/enums/stockStatusEnum';
2+
3+
export const cartGettersMock = (extend = {}) => ({
4+
getItems: jest.fn(() => []),
5+
getTotals: jest.fn(() => 0),
6+
getTotalItems: jest.fn(),
7+
getStockStatus: jest.fn(() => stockStatusEnum.inStock),
8+
...extend,
9+
});
10+
11+
export default cartGettersMock;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
export * from './useGuestUser';
22
export * from './useUser';
3+
export * from './useCart';
4+
export * from './useUiState';
5+
export * from './cartGetters';
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import stockStatusEnum from '~/enums/stockStatusEnum';
2+
3+
export const useEmptyCartMock = (cartData = {}) => ({
4+
load: jest.fn(),
5+
loading: {
6+
value: false,
7+
},
8+
removeItem: jest.fn(),
9+
updateItemQty: jest.fn(),
10+
cart: {
11+
value: {},
12+
},
13+
...cartData,
14+
});
15+
16+
export const useCartMock = (cartData = {}) => ({
17+
load: jest.fn(),
18+
loading: {
19+
value: false,
20+
},
21+
removeItem: jest.fn(),
22+
updateItemQty: jest.fn(),
23+
cart: {
24+
value: {
25+
items: [
26+
{
27+
product: {
28+
stock_status: stockStatusEnum.outOfStock,
29+
name: 'Test Product 1',
30+
sku: 'sku1',
31+
key: '1',
32+
image: 'https://image1.com',
33+
title: 'Title1',
34+
link: 'https://link1.com',
35+
},
36+
},
37+
{
38+
product: {
39+
stock_status: stockStatusEnum.inStock,
40+
name: 'Test Product 2',
41+
sku: 'sku2',
42+
key: '2',
43+
image: 'https://image2.com',
44+
title: 'Title2',
45+
link: 'https://link2.com',
46+
},
47+
},
48+
],
49+
total_quantity: 2,
50+
},
51+
},
52+
...cartData,
53+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export const useUiStateMock = (extend = {}) => ({
2+
isCartSidebarOpen: false,
3+
toggleCartSidebar: jest.fn(),
4+
...extend,
5+
});
6+
7+
export default useUiStateMock;

0 commit comments

Comments
 (0)