diff --git a/src/components/panelmenu/PanelMenu.spec.js b/src/components/panelmenu/PanelMenu.spec.js new file mode 100644 index 000000000..19c80b039 --- /dev/null +++ b/src/components/panelmenu/PanelMenu.spec.js @@ -0,0 +1,85 @@ +import { mount } from '@vue/test-utils'; +import PanelMenu from './PanelMenu.vue'; + +describe('PanelMenu', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(PanelMenu, { + global: { + stubs: { + 'router-link': true + } + }, + props: { + model: [ + { + key: '2', + label: 'Users', + icon: 'pi pi-fw pi-user', + items: [ + { + key: '2_0', + label: 'New', + icon: 'pi pi-fw pi-user-plus', + }, + { + key: '2_1', + label: 'Delete', + icon: 'pi pi-fw pi-user-minus', + }, + { + key: '2_2', + label: 'Search', + icon: 'pi pi-fw pi-users', + items: [ + { + key: '2_2_0', + label: 'Filter', + icon: 'pi pi-fw pi-filter', + items: [ + { + key: '2_2_0_0', + label: 'Print', + icon: 'pi pi-fw pi-print' + } + ] + }, + { + key: '2_2_1', + icon: 'pi pi-fw pi-bars', + label: 'List' + } + ] + } + ] + } + ] + } + }); + }); + + it('should exist', () => { + expect(wrapper.find('.p-panelmenu.p-component').exists()).toBe(true); + expect(wrapper.findAll('.p-menuitem').length).toBe(6); + expect(wrapper.findAll('.p-toggleable-content').length).toBe(7); + expect(wrapper.findAll('.p-submenu-list').length).toBe(3); + }); + + it('should toggle', async () => { + expect(wrapper.findAll('.p-toggleable-content')[0].attributes().style).toBe('display: none;'); + + await wrapper.vm.onItemClick({}, wrapper.vm.model[0]); + + expect(wrapper.find('.p-panelmenu-header-link > .p-panelmenu-icon').classes()).toContain('pi-chevron-down'); + expect(wrapper.findAll('.p-toggleable-content')[0].attributes().style).toBe(undefined); + }); + + it('should update expandedKeys', async () => { + await wrapper.setProps({ expandedKeys: {'2': true} }); + + await wrapper.vm.onItemClick({}, wrapper.vm.model[0].items[2]); + + expect(wrapper.emitted()['update:expandedKeys'][0]).toEqual([{ '2': true, '2_2': true }]); + }); +}); \ No newline at end of file diff --git a/src/components/password/Password.spec.js b/src/components/password/Password.spec.js new file mode 100644 index 000000000..6e109e0d6 --- /dev/null +++ b/src/components/password/Password.spec.js @@ -0,0 +1,58 @@ +import { mount } from '@vue/test-utils'; +import PrimeVue from '@/components/config/PrimeVue'; +import Password from './Password.vue'; + +describe('Password.vue', () => { + let wrapper; + const event = { target: {value: 'P'}}; + + beforeEach(async () => { + wrapper = mount(Password, { + global: { + plugins: [PrimeVue], + stubs: { + teleport: true + } + }, + props: { + modelValue: null + } + }); + + await wrapper.vm.onFocus(); + }); + + it('should exist', () => { + expect(wrapper.find('.p-password.p-component').exists()).toBe(true); + expect(wrapper.find('.p-password-panel').exists()).toBe(true); + }); + + it('should update modelValue', async () => { + await wrapper.vm.onInput(event); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['P']); + }); + + it('should meter update', async () => { + expect(wrapper.find('.p-password-info').text()).toBe('Enter a password'); + + await wrapper.vm.onKeyUp(event); + + expect(wrapper.find('.p-password-info').text()).toBe('Weak'); + + expect(wrapper.find('.p-password-strength').classes()).toContain('weak'); + }); + + it('should toggle mask', async () => { + await wrapper.setProps({ toggleMask: true }); + + expect(wrapper.find('.p-password-input').attributes().type).toBe('password'); + expect(wrapper.find('.pi.pi-eye').exists()).toBe(true); + + await wrapper.vm.onMaskToggle(); + + expect(wrapper.find('.p-password-input').attributes().type).toBe('text'); + expect(wrapper.find('.pi.pi-eye').exists()).toBe(false); + expect(wrapper.find('.pi.pi-eye-slash').exists()).toBe(true); + }); +}); \ No newline at end of file diff --git a/src/components/password/Password.vue b/src/components/password/Password.vue index 40d1f2ee2..4a3ef09d7 100755 --- a/src/components/password/Password.vue +++ b/src/components/password/Password.vue @@ -148,7 +148,7 @@ export default { return level; }, onInput(event) { - this.$emit('update:modelValue', event.target.value) + this.$emit('update:modelValue', event.target.value) }, onFocus() { this.focused = true; diff --git a/src/components/picklist/PickList.spec.js b/src/components/picklist/PickList.spec.js new file mode 100644 index 000000000..928b29f82 --- /dev/null +++ b/src/components/picklist/PickList.spec.js @@ -0,0 +1,169 @@ +import { mount } from '@vue/test-utils'; +import PickList from './PickList.vue'; + +describe('PickList.vue', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(PickList, { + props: { + modelValue: [ + [ + { + "id": "1000", + "code": "vbb124btr", + "name": "Game Controller", + "description": "Product Description", + "image": "game-controller.jpg", + "price": 99, + "category": "Electronics", + "quantity": 2, + "inventoryStatus": "LOWSTOCK", + "rating": 4 + }, + { + "id": "1001", + "code": "nvklal433", + "name": "Black Watch", + "description": "Product Description", + "image": "black-watch.jpg", + "price": 72, + "category": "Accessories", + "quantity": 61, + "inventoryStatus": "INSTOCK", + "rating": 4 + } + ], + [] + ] + }, + slots: { + sourceheader: 'Available', + targetheader: 'Selected' + } + }); + }); + + + it('should exist', () => { + expect(wrapper.find('.p-picklist.p-component').exists()).toBe(true); + expect(wrapper.find('.p-picklist-list-wrapper.p-picklist-source-wrapper').exists()).toBe(true); + expect(wrapper.find('.p-picklist-list-wrapper.p-picklist-target-wrapper').exists()).toBe(true); + }); + + it('should slots work', () => { + expect(wrapper.find('.p-picklist-source-wrapper > .p-picklist-header').text()).toBe('Available'); + expect(wrapper.find('.p-picklist-target-wrapper > .p-picklist-header').text()).toBe('Selected'); + }); + + it('should update sourceList and targetList', async () => { + await wrapper.setProps({ modelValue: [ + [ + { + "id": "1000", + "code": "vbb124btr", + "name": "Game Controller", + "description": "Product Description", + "image": "game-controller.jpg", + "price": 99, + "category": "Electronics", + "quantity": 2, + "inventoryStatus": "LOWSTOCK", + "rating": 4 + } + ], + [ + { + "id": "1001", + "code": "nvklal433", + "name": "Black Watch", + "description": "Product Description", + "image": "black-watch.jpg", + "price": 72, + "category": "Accessories", + "quantity": 61, + "inventoryStatus": "INSTOCK", + "rating": 4 + } + ] + ]}); + + expect(wrapper.vm.sourceList.length).toBe(1); + expect(wrapper.vm.targetList.length).toBe(1); + }); + + it('should select an item from source list', async () => { + await wrapper.vm.onItemClick({}, wrapper.vm.modelValue[0][0], 0); + + expect(wrapper.emitted()['update:selection'][0][0]).toEqual([[wrapper.vm.modelValue[0][0]], []]) + }); + + it('should dblclick an item from source list', async () => { + await wrapper.setProps({selection: [[wrapper.vm.modelValue[0][0]], []]}); + + await wrapper.vm.onItemDblClick({}, wrapper.vm.modelValue[0][0], 0); + + expect(wrapper.emitted()['update:modelValue'][0][0][1]).toEqual([wrapper.vm.modelValue[0][0]]); + expect(wrapper.emitted()['move-to-target'][0]).toEqual([{originalEvent: {}, items: [wrapper.vm.modelValue[0][0]]}]); + expect(wrapper.emitted()['update:selection'][0][0]).toEqual([[],[]]); + }); + + it('should move item up', async () => { + await wrapper.setProps({selection: [[wrapper.vm.modelValue[0][1]], []]}); + + await wrapper.vm.moveUp({}, 0); + + expect(wrapper.emitted()['update:modelValue'][0][0]).toEqual([[{ + "id": "1001", + "code": "nvklal433", + "name": "Black Watch", + "description": "Product Description", + "image": "black-watch.jpg", + "price": 72, + "category": "Accessories", + "quantity": 61, + "inventoryStatus": "INSTOCK", + "rating": 4 + },{ + "id": "1000", + "code": "vbb124btr", + "name": "Game Controller", + "description": "Product Description", + "image": "game-controller.jpg", + "price": 99, + "category": "Electronics", + "quantity": 2, + "inventoryStatus": "LOWSTOCK", + "rating": 4 + }],[]]); + }); + + it('should should move all to target', async () => { + await wrapper.vm.moveAllToTarget({}); + + expect(wrapper.emitted()['update:modelValue'][0][0]).toEqual([[], [{ + "id": "1000", + "code": "vbb124btr", + "name": "Game Controller", + "description": "Product Description", + "image": "game-controller.jpg", + "price": 99, + "category": "Electronics", + "quantity": 2, + "inventoryStatus": "LOWSTOCK", + "rating": 4 + }, + { + "id": "1001", + "code": "nvklal433", + "name": "Black Watch", + "description": "Product Description", + "image": "black-watch.jpg", + "price": 72, + "category": "Accessories", + "quantity": 61, + "inventoryStatus": "INSTOCK", + "rating": 4 + }]]); + }); +}); diff --git a/src/components/progressbar/ProgressBar.spec.js b/src/components/progressbar/ProgressBar.spec.js new file mode 100644 index 000000000..6825e07b9 --- /dev/null +++ b/src/components/progressbar/ProgressBar.spec.js @@ -0,0 +1,39 @@ +import { mount } from '@vue/test-utils'; +import ProgressBar from './ProgressBar.vue'; + +describe('ProgressBar.vue', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(ProgressBar, { + props: { + value: 0 + } + }); + }); + + it('should exist', () => { + expect(wrapper.find('.p-progressbar.p-component').exists()).toBe(true); + expect(wrapper.find('.p-progressbar').attributes()['aria-valuemin']).toBe('0'); + expect(wrapper.find('.p-progressbar').attributes()['aria-valuemax']).toBe('100'); + }); + + it('should value work', async () => { + await wrapper.setProps({ value: 10 }); + + expect(wrapper.find('.p-progressbar').attributes()['aria-valuenow']).toBe('10'); + expect(wrapper.find('.p-progressbar-label').text()).toBe('10%'); + }); + + it('should not show value', async () => { + await wrapper.setProps({ showValue: false }); + + expect(wrapper.find('.p-progressbar-label').exists()).toBe(false); + }); + + it('should be indeterminated', async () => { + await wrapper.setProps({ mode: 'indeterminate'}); + + expect(wrapper.find('.p-progressbar-indeterminate-container').exists()).toBe(true); + }); +}); \ No newline at end of file diff --git a/src/components/progressspinner/ProgressSpinner.spec.js b/src/components/progressspinner/ProgressSpinner.spec.js new file mode 100644 index 000000000..d1824aef6 --- /dev/null +++ b/src/components/progressspinner/ProgressSpinner.spec.js @@ -0,0 +1,24 @@ +import { mount } from '@vue/test-utils'; +import ProgressSpinner from './ProgressSpinner.vue'; + +describe('ProgressSpinner.vue', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(ProgressSpinner, { + props: { + strokeWidth: '8', + fill: 'green', + animationDuration: '.5s' + } + }); + }); + + it('should exist', () => { + expect(wrapper.find('.p-progress-spinner').exists()).toBe(true); + expect(wrapper.find('svg.p-progress-spinner-svg').exists()).toBe(true); + expect(wrapper.find('svg.p-progress-spinner-svg').attributes().style).toBe('animation-duration: .5s;'); + expect(wrapper.find('circle.p-progress-spinner-circle').attributes().fill).toBe('green'); + expect(wrapper.find('circle.p-progress-spinner-circle').attributes().strokeMiterlimit).toBe('10'); + }); +}); \ No newline at end of file diff --git a/src/components/radiobutton/RadioButton.spec.js b/src/components/radiobutton/RadioButton.spec.js new file mode 100644 index 000000000..c85106696 --- /dev/null +++ b/src/components/radiobutton/RadioButton.spec.js @@ -0,0 +1,34 @@ +import { mount } from '@vue/test-utils'; +import RadioButton from './RadioButton.vue'; + +describe('RadioButton.vue', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(RadioButton, { + props: { + value: 'Tatooine', + modelValue: null + } + }); + }); + + it('shoukd exist', () => { + expect(wrapper.find('.p-radiobutton.p-component').exists()).toBe(true); + expect(wrapper.find('input').attributes().type).toBe('radio'); + }); + + it('should clicked', async () => { + await wrapper.vm.onClick({}); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['Tatooine']); + expect(wrapper.emitted().change[0]).toEqual([{}]); + }); + + it('should checked', async () => { + await wrapper.setProps({ modelValue: 'Tatooine'}); + + expect(wrapper.vm.checked).toBe(true); + expect(wrapper.find('.p-radiobutton').classes()).toContain('p-radiobutton-checked'); + }); +}); \ No newline at end of file diff --git a/src/components/rating/Rating.spec.js b/src/components/rating/Rating.spec.js new file mode 100644 index 000000000..d2b8a4586 --- /dev/null +++ b/src/components/rating/Rating.spec.js @@ -0,0 +1,45 @@ +import { mount } from '@vue/test-utils'; +import Rating from './Rating.vue'; + +describe('Rating.vue', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(Rating); + }); + + it('should exist', () => { + expect(wrapper.find('.p-rating').exists()).toBe(true); + expect(wrapper.find('.p-rating-icon').exists()).toBe(true); + }); + + it('should update model', async () => { + await wrapper.vm.updateModel({}, 5); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual([5]); + expect(wrapper.emitted()['change'][0]).toEqual([{originalEvent: {}, value: 5}]); + }); + + it('should click', async () => { + await wrapper.vm.onStarClick({}, 1); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual([1]); + + await wrapper.setProps({ modelValue: 1 }); + + expect(wrapper.findAll('.p-rating-icon')[1].classes()).toContain('pi-star-fill'); + expect(wrapper.findAll('.p-rating-icon')[2].classes()).not.toContain('pi-star-fill'); + }); + + it('should cancel', async () => { + await wrapper.vm.onCancelClick({}); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual([null]); + }); + + it('should not cancel', async () => { + await wrapper.setProps({ cancel: false }); + + expect(wrapper.find('.p-rating-cancel').exists()).toBe(false); + }); +}); \ No newline at end of file diff --git a/src/components/rating/Rating.vue b/src/components/rating/Rating.vue index 3abbd4d60..37c754164 100755 --- a/src/components/rating/Rating.vue +++ b/src/components/rating/Rating.vue @@ -38,7 +38,7 @@ export default { this.updateModel(event, value); } }, - onCancelClick() { + onCancelClick(event) { if (!this.readonly && !this.disabled) { this.updateModel(event, null); } diff --git a/src/components/scrollpanel/ScrollPanel.spec.js b/src/components/scrollpanel/ScrollPanel.spec.js new file mode 100644 index 000000000..b8f174a18 --- /dev/null +++ b/src/components/scrollpanel/ScrollPanel.spec.js @@ -0,0 +1,51 @@ +import { shallowMount } from '@vue/test-utils'; +import ScrollPanel from './ScrollPanel.vue'; + +describe('ScrollPanel.vue', () => { + let wrapper; + + beforeEach(() => { + wrapper = shallowMount(ScrollPanel, { + slots: { + default: ` +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + Vitae et leo duis ut diam. + Ultricies mi quis hendrerit dolor magna eget est lorem. Amet consectetur adipiscing elit ut. + Nam libero justo laoreet sit amet. Pharetra massa massa ultricies mi quis hendrerit dolor magna. + Est ultricies integer quis auctor elit sed vulputate. Consequat ac felis donec et. Tellus orci ac auctor augue mauris. + Semper feugiat nibh sed pulvinar proin gravida hendrerit lectus a. Tincidunt arcu non sodales neque sodales. + Metus aliquam eleifend mi in nulla posuere sollicitudin aliquam ultrices. Sodales ut etiam sit amet nisl purus. + Cursus sit amet dictum sit amet. Tristique senectus et netus et malesuada fames ac turpis egestas. + Et tortor consequat id porta nibh venenatis cras sed. Diam maecenas ultricies mi eget mauris. + Eget egestas purus viverra accumsan in nisl nisi. Suscipit adipiscing bibendum est ultricies integer. + Mattis aliquam faucibus purus in massa tempor nec. +

+ ` + } + }); + + wrapper.element.setAttribute('width', '200px'); + wrapper.element.setAttribute('height', '200px'); + }); + + it('should exist', () => { + expect(wrapper.find('.p-scrollpanel.p-component').exists()).toBe(true); + }); + + it('should scroll down y', async () => { + const event = { pageY: 100, preventDefault: () => {} }; + + await wrapper.vm.onYBarMouseDown(event); + + expect(wrapper.find('.p-scrollpanel-bar-y').classes()).toContain('p-scrollpanel-grabbed'); + }); + + it('should scroll down x', async () => { + const event = { pageX: 100, preventDefault: () => {} }; + + await wrapper.vm.onXBarMouseDown(event); + + expect(wrapper.find('.p-scrollpanel-bar-x').classes()).toContain('p-scrollpanel-grabbed'); + }); +}); \ No newline at end of file diff --git a/src/components/scrolltop/ScrollTop.spec.js b/src/components/scrolltop/ScrollTop.spec.js new file mode 100644 index 000000000..edd5bc9d0 --- /dev/null +++ b/src/components/scrolltop/ScrollTop.spec.js @@ -0,0 +1,16 @@ +import { mount } from '@vue/test-utils'; +import ScrollTop from './ScrollTop.vue'; + +describe('ScrollTop.vue', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(ScrollTop); + }); + + it('should exist', async() => { + await wrapper.setData({ visible: true }); + + expect(wrapper.find('.p-scrolltop.p-component').exists()).toBe(true); + }); +}); \ No newline at end of file diff --git a/src/components/scrolltop/ScrollTop.vue b/src/components/scrolltop/ScrollTop.vue index b78e583a7..ab9d8aa05 100644 --- a/src/components/scrolltop/ScrollTop.vue +++ b/src/components/scrolltop/ScrollTop.vue @@ -56,7 +56,7 @@ export default { methods: { onClick() { let scrollElement = this.target === 'window' ? window : this.$el.parentElement; - scrollElement.scroll({ + scrollElement.scroll({ top: 0, behavior: this.behavior }); diff --git a/src/components/selectbutton/SelectButton.spec.js b/src/components/selectbutton/SelectButton.spec.js new file mode 100644 index 000000000..4a5387a0b --- /dev/null +++ b/src/components/selectbutton/SelectButton.spec.js @@ -0,0 +1,56 @@ +import { mount } from '@vue/test-utils'; +import SelectButton from './SelectButton.vue'; + +describe('SelectButton.vue', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(SelectButton, { + props: { + modelValue: null, + options: ['Off', 'On'] + } + }); + }); + + it('should exist', () => { + expect(wrapper.find('.p-selectbutton.p-component').exists()).toBe(true); + expect(wrapper.findAll('.p-button.p-component').length).toBe(2); + }); + + it('should option select', async () => { + await wrapper.vm.onOptionSelect({}, wrapper.vm.options[0]); + + expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['Off']); + + await wrapper.setProps({ modelValue: wrapper.vm.options[0] }); + + expect(wrapper.findAll('.p-button.p-component')[0].attributes()['aria-pressed']).toBe('true'); + expect(wrapper.findAll('.p-button.p-component')[0].classes()).toContain('p-highlight'); + }); +}); + +describe('multiple select', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(SelectButton, { + props: { + modelValue: null, + options: [ + {name: 'Option 1', value: 1}, + {name: 'Option 2', value: 2}, + {name: 'Option 3', value: 3} + ], + optionLabel: 'name', + multiple: true + } + }); + }); + + it('should select', async () => { + await wrapper.setProps({ modelValue: wrapper.vm.options }); + + expect(wrapper.findAll('.p-highlight').length).toBe(3); + }); +}); \ No newline at end of file diff --git a/src/components/sidebar/Sidebar.spec.js b/src/components/sidebar/Sidebar.spec.js new file mode 100644 index 000000000..eda571e6f --- /dev/null +++ b/src/components/sidebar/Sidebar.spec.js @@ -0,0 +1,54 @@ +import { mount } from '@vue/test-utils'; +import PrimeVue from '@/components/config/PrimeVue'; +import Sidebar from './Sidebar.vue'; + +describe('Sidebar.vue', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(Sidebar, { + global: { + plugins: [PrimeVue], + stubs: { + teleport: true + } + }, + props: { + visible: true, + bazeZIndex: 1000 + }, + slots: { + default: `

Left Sidebar

` + } + }); + }); + + it('should exist', () => { + expect(wrapper.find('.p-sidebar.p-component').exists()).toBe(true); + expect(wrapper.find('.p-sidebar').classes()).toContain('p-sidebar-left'); + expect(wrapper.find('.p-sidebar').classes()).toContain('p-sidebar-active'); + }); + + it('should close', async () => { + await wrapper.vm.hide(); + + expect(wrapper.emitted()['update:visible'][0]).toEqual([false]); + + await wrapper.setProps({ visible: false }); + + expect(wrapper.find('.p-sidebar.p-component').exists()).toBe(false); + }); + + it('should set position', async () => { + await wrapper.setProps({ position: 'bottom' }); + + expect(wrapper.find('.p-sidebar').classes()).toContain('p-sidebar-bottom'); + }); + + it('should set position', async () => { + await wrapper.setProps({ position: 'full' }); + + expect(wrapper.vm.fullScreen).toBe(true); + expect(wrapper.find('.p-sidebar').classes()).toContain('p-sidebar-full'); + }); +}); \ No newline at end of file diff --git a/src/components/skeleton/Skeleton.spec.js b/src/components/skeleton/Skeleton.spec.js new file mode 100644 index 000000000..954a3e461 --- /dev/null +++ b/src/components/skeleton/Skeleton.spec.js @@ -0,0 +1,38 @@ +import { mount } from '@vue/test-utils'; +import Skeleton from './Skeleton.vue'; + +describe('Skeleton.vue', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(Skeleton); + }); + + it('should exist', () => { + expect(wrapper.find('.p-skeleton.p-component').exists()).toBe(true); + }); + + it('should get width and height', async () => { + await wrapper.setProps({ width: '5rem', height: '2rem', borderRadius: '10px' }); + + expect(wrapper.find('.p-skeleton').attributes().style).toEqual('width: 5rem; height: 2rem; border-radius: 10px;'); + }); + + it('should get size', async () => { + await wrapper.setProps({ size: '4rem' }); + + expect(wrapper.find('.p-skeleton').attributes().style).toEqual('width: 4rem; height: 4rem;'); + }); + + it('should get shape', async () => { + await wrapper.setProps({ shape: 'circle' }); + + expect(wrapper.find('.p-skeleton').classes()).toContain('p-skeleton-circle'); + }); + + it('should remove animation', async () => { + await wrapper.setProps({ animation: 'none' }); + + expect(wrapper.find('.p-skeleton').classes()).toContain('p-skeleton-none'); + }); +});