Skip to content

Commit 0e65dfd

Browse files
sethiddenMarcin Kwiatkowski
authored andcommitted
test: add BottomNavigation tests (#1114)
1 parent 524c1a5 commit 0e65dfd

File tree

4 files changed

+179
-5
lines changed

4 files changed

+179
-5
lines changed

packages/theme/components/BottomNavigation.vue

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
<SfBottomNavigationItem
55
:class="{ 'sf-bottom-navigation__item--active': $route.name && $route.name.startsWith('home') }"
66
label="Home"
7-
@click="$router.push(app.localePath('/')) && (isMobileMenuOpen ? toggleMobileMenu() : false)"
7+
data-testid="bottom-navigation-home"
8+
@click="handleHomeClick"
89
>
910
<template #icon>
1011
<SvgImage
@@ -17,6 +18,7 @@
1718
</SfBottomNavigationItem>
1819
<SfBottomNavigationItem
1920
label="Menu"
21+
data-testid="bottom-navigation-menu"
2022
@click="loadCategoryMenu"
2123
>
2224
<template #icon>
@@ -31,6 +33,7 @@
3133
<SfBottomNavigationItem
3234
v-if="isAuthenticated"
3335
label="Wishlist"
36+
data-testid="bottom-navigation-wishlist"
3437
@click="toggleWishlistSidebar"
3538
>
3639
<template #icon>
@@ -44,6 +47,7 @@
4447
</SfBottomNavigationItem>
4548
<SfBottomNavigationItem
4649
label="Account"
50+
data-testid="bottom-navigation-account"
4751
@click="handleAccountClick"
4852
>
4953
<template #icon>
@@ -57,6 +61,7 @@
5761
</SfBottomNavigationItem>
5862
<SfBottomNavigationItem
5963
:label="$route.name && $route.name.startsWith('product') ? 'Add to Cart' : 'Basket'"
64+
data-testid="bottom-navigation-cart"
6065
@click="toggleCartSidebar"
6166
>
6267
<template #icon>
@@ -78,14 +83,15 @@
7883
<script lang="ts">
7984
import { SfBottomNavigation, SfCircleIcon } from '@storefront-ui/vue';
8085
import { defineComponent, useRouter, useContext } from '@nuxtjs/composition-api';
81-
import { useUiState } from '~/composables';
86+
import { useUiState } from '~/composables/useUiState';
8287
import { useUser } from '~/modules/customer/composables/useUser';
8388
import SvgImage from '~/components/General/SvgImage.vue';
8489
import { useCategoryStore } from '~/modules/catalog/category/stores/category';
8590
8691
const MobileCategorySidebar = () => import('~/modules/catalog/category/components/sidebar/MobileCategorySidebar/MobileCategorySidebar.vue');
8792
8893
export default defineComponent({
94+
name: 'BottomNavigation',
8995
components: {
9096
SfBottomNavigation,
9197
SfCircleIcon,
@@ -103,6 +109,15 @@ export default defineComponent({
103109
const { isAuthenticated } = useUser();
104110
const router = useRouter();
105111
const { app } = useContext();
112+
113+
const handleHomeClick = async () => {
114+
const homePath = app.localeRoute({ name: 'home' });
115+
await router.push(homePath);
116+
if (isMobileMenuOpen) {
117+
toggleMobileMenu();
118+
}
119+
};
120+
106121
const handleAccountClick = async () => {
107122
if (isAuthenticated.value) {
108123
await router.push(app.localeRoute({ name: 'customer' }));
@@ -127,7 +142,7 @@ export default defineComponent({
127142
toggleMobileMenu,
128143
loadCategoryMenu,
129144
handleAccountClick,
130-
app,
145+
handleHomeClick,
131146
};
132147
},
133148
});
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import { render, waitFor } from '@testing-library/vue';
2+
import userEvent from '@testing-library/user-event';
3+
4+
import { createLocalVue } from '@vue/test-utils';
5+
import { PiniaVuePlugin } from 'pinia';
6+
import { createTestingPinia } from '@pinia/testing';
7+
import { ref } from '@nuxtjs/composition-api';
8+
import { useUser } from '~/modules/customer/composables/useUser';
9+
import { useUiState } from '~/composables';
10+
import { useUiStateMock, useUserMock } from '~/test-utils';
11+
12+
import { useCategoryStore } from '~/modules/catalog/category/stores/category';
13+
import BottomNavigation from '../BottomNavigation.vue';
14+
15+
jest.mock('~/composables/useUiState', () => ({
16+
useUiState: jest.fn(),
17+
}));
18+
19+
jest.mock('~/modules/customer/composables/useUser', () => ({
20+
useUser: jest.fn(),
21+
}));
22+
23+
(useUser as jest.Mock).mockReturnValue(useUserMock());
24+
(useUiState as jest.Mock).mockReturnValue(useUiStateMock());
25+
26+
const localVue = createLocalVue();
27+
localVue.use(PiniaVuePlugin);
28+
29+
describe('BottomNavigation', () => {
30+
it('handles "Home" button click', async () => {
31+
const routerPushMock = jest.fn();
32+
33+
const { getByTestId } = render(
34+
BottomNavigation,
35+
{
36+
mocks: {
37+
$router: {
38+
push: routerPushMock,
39+
},
40+
$route: {
41+
name: 'home',
42+
},
43+
},
44+
localVue,
45+
pinia: createTestingPinia(),
46+
},
47+
);
48+
49+
const homeButton = getByTestId('bottom-navigation-home');
50+
userEvent.click(homeButton);
51+
await waitFor(() => {
52+
expect(routerPushMock).toHaveBeenCalledWith({ name: 'home' });
53+
});
54+
});
55+
it('handles "Menu" (categories) button click', async () => {
56+
const { getByTestId } = render(
57+
BottomNavigation,
58+
{
59+
mocks: {
60+
$route: {
61+
name: 'home',
62+
},
63+
},
64+
localVue,
65+
pinia: createTestingPinia(),
66+
},
67+
);
68+
69+
const categoryStore = useCategoryStore();
70+
71+
const menuButton = getByTestId('bottom-navigation-menu');
72+
userEvent.click(menuButton);
73+
await waitFor(() => {
74+
expect(categoryStore.load).toHaveBeenCalled();
75+
});
76+
});
77+
it('handles "Wishlist" button click', async () => {
78+
const useUiStateMockInstance = useUiStateMock();
79+
(useUiState as jest.Mock).mockReturnValueOnce(useUiStateMockInstance);
80+
const useUserMockInstance = useUserMock({ isAuthenticated: ref(true) });
81+
(useUser as jest.Mock).mockReturnValueOnce(useUserMockInstance);
82+
83+
const { getByTestId } = render(
84+
BottomNavigation,
85+
{
86+
mocks: {
87+
$route: {
88+
name: 'home',
89+
},
90+
},
91+
localVue,
92+
pinia: createTestingPinia(),
93+
},
94+
);
95+
96+
const wishlistButton = getByTestId('bottom-navigation-wishlist');
97+
userEvent.click(wishlistButton);
98+
await waitFor(() => {
99+
expect(useUiStateMockInstance.toggleWishlistSidebar).toHaveBeenCalled();
100+
});
101+
});
102+
it('handles "Account" button click', async () => {
103+
const useUiStateMockInstance = useUiStateMock();
104+
(useUiState as jest.Mock).mockReturnValueOnce(useUiStateMockInstance);
105+
const useUserMockInstance = useUserMock({ isAuthenticated: ref(true) });
106+
(useUser as jest.Mock).mockReturnValueOnce(useUserMockInstance);
107+
108+
const routerPushMock = jest.fn();
109+
110+
const { getByTestId } = render(
111+
BottomNavigation,
112+
{
113+
mocks: {
114+
$router: {
115+
push: routerPushMock,
116+
},
117+
$route: {
118+
name: 'home',
119+
},
120+
},
121+
localVue,
122+
pinia: createTestingPinia(),
123+
},
124+
);
125+
126+
const accountButton = getByTestId('bottom-navigation-account');
127+
userEvent.click(accountButton);
128+
await waitFor(() => {
129+
expect(routerPushMock).toHaveBeenCalledWith({ name: 'customer' });
130+
});
131+
});
132+
it('handles "Cart" button click', async () => {
133+
const useUiStateMockInstance = useUiStateMock();
134+
(useUiState as jest.Mock).mockReturnValueOnce(useUiStateMockInstance);
135+
const useUserMockInstance = useUserMock({ isAuthenticated: ref(true) });
136+
(useUser as jest.Mock).mockReturnValueOnce(useUserMockInstance);
137+
138+
const { getByTestId } = render(
139+
BottomNavigation,
140+
{
141+
mocks: {
142+
$route: {
143+
name: 'home',
144+
},
145+
},
146+
localVue,
147+
pinia: createTestingPinia(),
148+
},
149+
);
150+
151+
const cartButton = getByTestId('bottom-navigation-cart');
152+
userEvent.click(cartButton);
153+
await waitFor(() => {
154+
expect(useUiStateMockInstance.toggleCartSidebar).toHaveBeenCalled();
155+
});
156+
});
157+
});

packages/theme/jest-setup.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ config.mocks = {
99
$t: (text) => text,
1010
$fc: (text) => text,
1111
localePath: (text) => text,
12+
localeRouter: (route) => route,
1213
};
1314

1415
const $vsf = {
@@ -28,7 +29,7 @@ Vue.prototype.$nuxt = {
2829
context: {
2930
$vsf,
3031
$fc: jest.fn((label) => label),
31-
localeRoute: jest.fn(() => 'some_url'),
32+
localeRoute: jest.fn((route) => route),
3233
localePath: jest.fn((link) => link),
3334
app: {
3435
// $vsf intentionally doubled in context top level AND in context.app - this is the way it's in the app
@@ -38,7 +39,7 @@ Vue.prototype.$nuxt = {
3839
},
3940
$fc: jest.fn((label) => label),
4041
localePath: jest.fn((link) => link),
41-
localeRoute: jest.fn(() => 'some_url'),
42+
localeRoute: jest.fn((path) => path),
4243
},
4344
i18n: {
4445
t: jest.fn((label) => label),

packages/theme/test-utils/mocks/useUiState.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const useUiStateMock = (extend = {}) => ({
44
changeToCategoryListView: jest.fn(),
55
toggleCartSidebar: jest.fn(),
66
toggleFilterSidebar: jest.fn(),
7+
toggleWishlistSidebar: jest.fn(),
78
toggleMobileMenu: jest.fn(),
89
...extend,
910
});

0 commit comments

Comments
 (0)