Skip to content

Commit

Permalink
test: add SidebarItem test
Browse files Browse the repository at this point in the history
  • Loading branch information
mateuseduardomedeiros committed Nov 12, 2024
1 parent 65383e7 commit 18f0e38
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 9 deletions.
29 changes: 20 additions & 9 deletions src/components/Sidebar/SidebarItem.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
<template>
<section
data-testid="sidebar-item"
:class="{ 'unnnic-sidebar-item': true, active: active.item }"
@click.stop="hasChildren ? handleShowChildrenList() : handleEmitNavigate()"
@click.stop="handleClick"
>
<Icon
v-if="item.icon"
class="unnnic-sidebar-item__icon"
:icon="item.icon"
size="ant"
:scheme="active.item ? 'weni-600' : 'neutral-cloudy'"
data-testid="item-icon"
/>
<p :class="{ 'unnnic-sidebar-item__label': true, active: active.item }" :title="item.label">
<p
:class="{ 'unnnic-sidebar-item__label': true, active: active.item }"
:title="item.label"
>
{{ item.label }}
</p>
<Icon
Expand All @@ -19,6 +24,7 @@
:icon="showChildrenList ? 'keyboard_arrow_up' : 'keyboard_arrow_down'"
size="ant"
scheme="neutral-cloudy"
data-testid="arrow-icon"
/>
</section>
<Transition name="slide-fade">
Expand All @@ -33,6 +39,7 @@
'unnnic-sidebar-item-child': true,
active: isActive(childIndex),
}"
data-testid="sidebar-item-child"
@click.stop="!isActive(childIndex) && emit('navigate', { item, child })"
>
<Icon
Expand Down Expand Up @@ -79,8 +86,8 @@ const props = defineProps({
},
autoNavigateFirstChild: {
type: Boolean,
default: false
}
default: false,
},
});
onMounted(() => {
Expand All @@ -91,21 +98,21 @@ onMounted(() => {
});
const hasChildren = computed(() => {
return props.item.children?.length;
return !!props.item.children?.length;
});
const showChildrenList = ref(false);
const handleShowChildrenList = () => {
showChildrenList.value = !showChildrenList.value;
const isOpening = showChildrenList.value
if (isOpening && props.autoNavigateFirstChild) {
const isOpening = showChildrenList.value;
if (isOpening && props.autoNavigateFirstChild) {
emit('navigate', { item: props.item, child: props.item.children[0] });
}
};
const isActive = (paramChildIndex = null) => {
const isActive = (paramChildIndex) => {
const { item, childIndex } = props.active;
if (!(typeof childIndex === 'number')) {
return item;
Expand All @@ -114,6 +121,10 @@ const isActive = (paramChildIndex = null) => {
return item && childIndex === paramChildIndex;
};
const handleClick = () => {
hasChildren.value ? handleShowChildrenList() : handleEmitNavigate();
};
const handleEmitNavigate = () => {
if (!props.active.item) {
emit('navigate', { item: props.item, child: null });
Expand Down
105 changes: 105 additions & 0 deletions src/components/Sidebar/__tests__/SidebarItem.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { mount } from '@vue/test-utils';
import { describe, it, expect, beforeEach, vi } from 'vitest';

import SidebarItem from '../SidebarItem.vue';

const item = {
label: 'Parent Item',
icon: 'parent-icon',
children: [
{ label: 'Child Item 1', icon: 'child-icon-1' },
{ label: 'Child Item 2', icon: 'child-icon-2' },
],
};

describe('SidebarItem', () => {
let wrapper;

beforeEach(() => {
wrapper = mount(SidebarItem, {
props: {
item,
active: { item: null, childIndex: null },
},
global: {
stubs: {
Icon: true,
},
},
});
});

it('renders the component with required props', () => {
expect(wrapper.exists()).toBe(true);
expect(wrapper.text()).toContain(item.label);
});

it('renders the item icon and toggle arrow icon when there are children', () => {
expect(wrapper.find('[data-testid="item-icon"]').exists()).toBe(true);
expect(wrapper.find('[data-testid="arrow-icon"]').exists()).toBe(true);
});

it('emits "navigate" when item is clicked and has no children', async () => {
await wrapper.setProps({
item: { label: 'Single Item', icon: 'single-icon' },
});

const sidebarItem = wrapper.find('[data-testid="sidebar-item"]');

await sidebarItem.trigger('click');

expect(wrapper.emitted('navigate')).toBeTruthy();
expect(wrapper.emitted('navigate')[0][0]).toEqual({
item: { label: 'Single Item', icon: 'single-icon' },
child: null,
});
});

it('should not emit navigation event if the item is active', async () => {
await wrapper.setProps({
item: { label: 'Single Item', icon: 'single-icon' },
active: { item: true, childIndex: null },
});
const sidebarItem = wrapper.find('[data-testid="sidebar-item"]');

await sidebarItem.trigger('click');

expect(wrapper.emitted('navigate')).toBeFalsy();
});

it('toggles showChildrenList and emits "navigate" when child item is clicked', async () => {
await wrapper.find('[data-testid="sidebar-item"]').trigger('click');
expect(wrapper.vm.showChildrenList).toBe(true);

await wrapper
.findAll('[data-testid="sidebar-item-child"]')[1]
.trigger('click');
expect(wrapper.emitted('navigate')).toBeTruthy();
expect(wrapper.emitted('navigate')[0][0]).toEqual({
item,
child: item.children[1],
});
});

it('automatically navigates to the first child if autoNavigateFirstChild is true', async () => {
await wrapper.setProps({ autoNavigateFirstChild: true });

await wrapper.find('[data-testid="sidebar-item"]').trigger('click');
expect(wrapper.emitted('navigate')).toBeTruthy();
expect(wrapper.emitted('navigate')[0][0]).toEqual({
item,
child: item.children[0],
});
});

it('calls handleShowChildrenList on mount if active.childIndex is a valid number and active.item is true', async () => {
const wrapper = mount(SidebarItem, {
props: {
item,
active: { item: true, childIndex: 0 },
},
});

expect(wrapper.vm.showChildrenList).toBe(true);
});
});

0 comments on commit 18f0e38

Please sign in to comment.