UNPKG

vuetify

Version:

Vue Material Component Framework

540 lines (424 loc) 14 kB
// Components import VNavigationDrawer from '../VNavigationDrawer' // Services import { Application } from '../../../services/application' import { Breakpoint } from '../../../services/breakpoint' import { preset } from '../../../presets/default' // Utilities import { resizeWindow, touch, } from '../../../../test' import { mount, MountOptions, Wrapper, } from '@vue/test-utils' beforeEach(() => resizeWindow(1920, 1080)) describe('VNavigationDrawer', () => { // eslint-disable-line max-statements type Instance = InstanceType<typeof VNavigationDrawer> let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance> beforeEach(() => { mountFunction = (options?: MountOptions<Instance>) => { const breakpoint = new Breakpoint(preset) breakpoint.init() return mount(VNavigationDrawer, { ...options, mocks: { $vuetify: { rtl: false, theme: { dark: false, }, breakpoint, application: new Application(), }, }, }) } }) it('should become temporary when the window resizes', async () => { const wrapper = mountFunction({ propsData: { app: true }, }) expect(wrapper.vm.isActive).toBe(true) await resizeWindow(1200) wrapper.vm.$vuetify.breakpoint.width = 1200 expect(wrapper.vm.isActive).toBe(false) expect(wrapper.vm.overlay).toBeFalsy() }) it('should not resize the content when temporary', async () => { const wrapper = mountFunction({ propsData: { app: true, temporary: true, value: true, }, }) await wrapper.vm.$nextTick() expect(wrapper.vm.$vuetify.application.left).toBe(0) expect(wrapper.vm.overlay).toBeTruthy() }) it('should not resize the content when permanent and stateless', async () => { const wrapper = mountFunction({ propsData: { app: true, permanent: true, stateless: true, }, }) await wrapper.vm.$nextTick() expect(wrapper.vm.$vuetify.application.left).toBe(256) await resizeWindow(1200) expect(wrapper.vm.$vuetify.application.left).toBe(256) expect(wrapper.vm.overlay).toBeFalsy() }) it('should not resize the content when permanent and resize watcher is disabled', async () => { const wrapper = mountFunction({ propsData: { app: true, permanent: true, disableResizeWatcher: true, }, }) await wrapper.vm.$nextTick() expect(wrapper.vm.$vuetify.application.left).toBe(256) await resizeWindow(1200) expect(wrapper.vm.$vuetify.application.left).toBe(256) expect(wrapper.vm.overlay).toBeFalsy() }) it('should stay active when resizing a temporary drawer', async () => { const wrapper = mountFunction({ propsData: { app: true, temporary: true, value: true, }, }) await wrapper.vm.$nextTick() expect(wrapper.vm.isActive).toBe(true) expect(wrapper.vm.overlay).toBeTruthy() await resizeWindow(1200) expect(wrapper.vm.isActive).toBe(true) expect(wrapper.vm.overlay).toBeTruthy() }) it('should open when changed to permanent', async () => { const wrapper = mountFunction({ propsData: { value: null, }, }) wrapper.setProps({ permanent: true }) await wrapper.vm.$nextTick() expect(wrapper.vm.isActive).toBe(true) }) it('should not close when value changes and permanent', async () => { const wrapper = mountFunction({ propsData: { permanent: true, value: true, }, }) wrapper.setProps({ value: false }) await wrapper.vm.$nextTick() expect(wrapper.vm.isActive).toBe(true) }) it('should update content padding when temporary state is changed', async () => { const wrapper = mountFunction({ propsData: { app: true, }, }) await wrapper.vm.$nextTick() expect(wrapper.vm.$vuetify.application.left).toBe(256) wrapper.setProps({ temporary: true }) expect(wrapper.vm.$vuetify.application.left).toBe(0) wrapper.setProps({ temporary: false }) expect(wrapper.vm.$vuetify.application.left).toBe(256) }) it('should update content padding when permanent state is changed', async () => { const wrapper = mountFunction({ propsData: { app: true, }, }) await resizeWindow(800) wrapper.vm.$vuetify.breakpoint.width = 800 await wrapper.vm.$nextTick() expect(wrapper.vm.$vuetify.application.left).toBe(0) wrapper.setProps({ permanent: true }) expect(wrapper.vm.$vuetify.application.left).toBe(256) wrapper.setProps({ permanent: false }) expect(wrapper.vm.$vuetify.application.left).toBe(0) }) it('should update content padding when miniVariant is changed', async () => { const wrapper = mountFunction({ propsData: { app: true, }, }) await wrapper.vm.$nextTick() expect(wrapper.vm.$vuetify.application.left).toBe(256) wrapper.setProps({ miniVariant: true }) expect(wrapper.vm.$vuetify.application.left).toBe(56) wrapper.setProps({ miniVariant: false }) expect(wrapper.vm.$vuetify.application.left).toBe(256) }) it('should not remain mobile when temporary is toggled', async () => { await resizeWindow(800) const wrapper = mountFunction({ propsData: { temporary: true, }, }) await resizeWindow(1920) expect(wrapper.vm.isMobile).toBe(false) }) it('should stay closed when mobile and temporary is enabled', async () => { const wrapper = mountFunction({ propsData: { app: true }, }) await resizeWindow(800) wrapper.vm.$vuetify.breakpoint.width = 800 await wrapper.vm.$nextTick() const input = jest.fn(value => wrapper.setProps({ value })) wrapper.vm.$on('input', input) wrapper.setProps({ temporary: true }) await wrapper.vm.$nextTick() expect(wrapper.vm.isActive).toBe(false) expect(input.mock.calls).toHaveLength(0) }) it('should update content padding when mobile is toggled', async () => { const input = jest.fn() const wrapper = mountFunction({ propsData: { app: true, fixed: true, value: true, }, }) await wrapper.vm.$nextTick() wrapper.vm.$on('input', input) expect(wrapper.vm.$vuetify.application.left).toBe(256) await resizeWindow(800) wrapper.vm.$vuetify.breakpoint.width = 800 expect(wrapper.vm.$vuetify.application.left).toBe(0) expect(wrapper.vm.isActive).toBe(false) expect(input).toHaveBeenCalledWith(false) wrapper.setProps({ value: false }) await wrapper.vm.$nextTick() wrapper.setProps({ value: true }) await wrapper.vm.$nextTick() expect(wrapper.vm.isActive).toBe(true) expect(wrapper.vm.$vuetify.application.left).toBe(0) await resizeWindow(1920) wrapper.vm.$vuetify.breakpoint.width = 1920 expect(wrapper.vm.isActive).toBe(true) expect(wrapper.vm.isMobile).toBe(false) expect(wrapper.vm.$vuetify.application.left).toBe(256) }) it('should not have marginTop when temporary / isMobile', async () => { const wrapper = mountFunction({ propsData: { app: true, }, }) wrapper.vm.$vuetify.application.bar = 0 expect(wrapper.vm.computedTop).toBe(0) wrapper.vm.$vuetify.application.bar = 24 await wrapper.vm.$nextTick() expect(wrapper.vm.computedTop).toBe(24) await resizeWindow(640) wrapper.vm.$vuetify.breakpoint.width = 640 expect(wrapper.vm.computedTop).toBe(0) await resizeWindow(1980) wrapper.vm.$vuetify.breakpoint.width = 1980 expect(wrapper.vm.computedTop).toBe(24) wrapper.setProps({ temporary: true }) await wrapper.vm.$nextTick() expect(wrapper.vm.computedTop).toBe(0) wrapper.setProps({ app: false, temporary: false }) await wrapper.vm.$nextTick() expect(wrapper.vm.computedTop).toBe(0) wrapper.setProps({ app: true }) expect(wrapper.vm.computedTop).toBe(24) }) it('should react to mini-variant clicks', () => { const update = jest.fn() const wrapper = mountFunction({ propsData: { miniVariant: true, }, listeners: { 'update:mini-variant': update, }, }) wrapper.trigger('click') expect(update).toHaveBeenCalled() }) it('should open on mouseenter when mini-variant = true and expand-on-hover = true', async () => { const update = jest.fn() const wrapper = mountFunction({ propsData: { miniVariant: true, expandOnHover: true, }, listeners: { 'update:mini-variant': update, }, }) wrapper.trigger('mouseenter') await wrapper.vm.$nextTick() expect(update).toHaveBeenCalledWith(false) expect(wrapper.classes('v-navigation-drawer--open-on-hover')).toBe(true) expect(wrapper.classes('v-navigation-drawer--mini-variant')).toBe(false) }) it('should emit `update:mini-variant` when mouseenter/mouseleave', async () => { const calls: string[] = [] const update = jest.fn(val => calls.push(val)) const wrapper = mountFunction({ propsData: { miniVariant: true, expandOnHover: true, }, listeners: { 'update:mini-variant': (value: boolean) => { wrapper.setProps({ miniVariant: value }) update(value) }, }, }) wrapper.trigger('mouseenter') await wrapper.vm.$nextTick() wrapper.trigger('mouseleave') await wrapper.vm.$nextTick() expect(calls).toEqual([false, true]) }) it('should emit `update:mini-variant` when expandOnHover has been changed', async () => { const calls: string[] = [] const update = jest.fn(val => calls.push(val)) const wrapper = mountFunction({ propsData: { miniVariant: false, expandOnHover: false, }, listeners: { 'update:mini-variant': (value: boolean) => { wrapper.setProps({ miniVariant: value }) update(value) }, }, }) wrapper.setProps({ expandOnHover: true }) await wrapper.vm.$nextTick() wrapper.setProps({ expandOnHover: false }) await wrapper.vm.$nextTick() expect(calls).toEqual([true, false]) }) it('should react to open / close from touch events', async () => { const wrapper = mountFunction({ attachToDocument: true, propsData: { value: false }, }) const element = wrapper.vm.$el.parentElement expect(wrapper.vm.isActive).toBe(false) touch({ element }).start(0, 0).end(200, 0) expect(wrapper.vm.isActive).toBe(true) // A consecutive swipe should keep the same state touch({ element }).start(0, 0).end(200, 0) expect(wrapper.vm.isActive).toBe(true) touch({ element }).start(200, 0).end(0, 0) expect(wrapper.vm.isActive).toBe(false) // A consecutive swipe should keep the same state touch({ element }).start(200, 0).end(0, 0) expect(wrapper.vm.isActive).toBe(false) // Swipe is not long enough touch({ element }).start(0, 0).end(99, 0) expect(wrapper.vm.isActive).toBe(false) wrapper.setProps({ right: true }) // Swipe is not long enough touch({ element }).start(1920, 0).end(1821, 0) expect(wrapper.vm.isActive).toBe(false) touch({ element }).start(1920, 0).end(1720, 0) expect(wrapper.vm.isActive).toBe(true) // A consecutive swipe should keep the same state touch({ element }).start(1920, 0).end(1720, 0) expect(wrapper.vm.isActive).toBe(true) touch({ element }).start(1720, 0).end(1920, 0) expect(wrapper.vm.isActive).toBe(false) }) it('should activate and expand on hover', () => { const wrapper = mountFunction({ propsData: { expandOnHover: true, }, }) expect(wrapper.vm.isMouseover).toBe(false) expect(wrapper.vm.computedWidth).toBe(56) wrapper.trigger('mouseenter') expect(wrapper.vm.isMouseover).toBe(true) expect(wrapper.vm.computedWidth).toBe(256) wrapper.trigger('mouseleave') expect(wrapper.vm.isMouseover).toBe(false) expect(wrapper.vm.computedWidth).toBe(56) }) it('should clip top', () => { const wrapper = mountFunction({ propsData: { app: true, clipped: true, }, }) wrapper.vm.$vuetify.application.bottom = 20 wrapper.vm.$vuetify.application.top = 40 expect(wrapper.vm.computedMaxHeight).toBe(60) }) it('should close when route changes on mobile', async () => { const wrapper = mountFunction({ propsData: { app: true, disableRouteWatcher: true, }, }) expect(wrapper.vm.isActive).toBe(true) wrapper.vm.onRouteChange() expect(wrapper.vm.isActive).toBe(true) wrapper.setProps({ disableRouteWatcher: false, stateless: true, }) wrapper.vm.onRouteChange() expect(wrapper.vm.isActive).toBe(true) wrapper.setProps({ stateless: false, temporary: true, }) wrapper.vm.onRouteChange() expect(wrapper.vm.isActive).toBe(false) wrapper.setProps({ temporary: false, value: true, }) await wrapper.vm.$nextTick() // Wait for value watcher to fire expect(wrapper.vm.isActive).toBe(true) wrapper.vm.onRouteChange() expect(wrapper.vm.isActive).toBe(true) await resizeWindow(400) wrapper.vm.$vuetify.breakpoint.width = 400 await wrapper.vm.$nextTick() wrapper.vm.onRouteChange() expect(wrapper.vm.isActive).toBe(false) }) it('should accept custom tag and have default based upon app prop', () => { const wrapper = mountFunction() expect(wrapper.vm.tag).toBe('aside') const wrapper2 = mountFunction({ propsData: { app: true }, }) expect(wrapper2.vm.tag).toBe('nav') const wrapper3 = mountFunction({ propsData: { tag: 'div' }, }) expect(wrapper3.vm.tag).toBe('div') }) })