diff --git a/frontend/src/components/#SessionLogoutTimeout.spec.js# b/frontend/src/components/#SessionLogoutTimeout.spec.js# new file mode 100644 index 000000000..1368366b2 --- /dev/null +++ b/frontend/src/components/#SessionLogoutTimeout.spec.js# @@ -0,0 +1,98 @@ +import { mount } from '@vue/test-utils' +import SessionLogoutTimeout from './SessionLogoutTimeout' + +const localVue = global.localVue + +const apolloQueryMock = jest.fn() + +const setTokenTime = (seconds) => { + const now = new Date() + return Math.floor(new Date(now.setSeconds(now.getSeconds() + seconds)).getTime() / 1000) +} + +const mocks = { + $store: { + state: { + token: '1234', + tokenTime: setTokenTime(120), + }, + }, + $i18n: { + locale: 'en', + }, + $t: jest.fn((t) => t), + $apollo: { + query: apolloQueryMock, + }, + $route: { + meta: { + requiresAuth: true, + }, + }, +} + +describe('SessionLogoutTimeout', () => { + let wrapper, spy + + const Wrapper = () => { + return mount(SessionLogoutTimeout, { localVue, mocks }) + } + + describe('mount', () => { + beforeEach(() => { + jest.clearAllMocks() + wrapper = Wrapper() + }) + + it('renders the component div.session-logout-timeout', () => { + expect(wrapper.find('div.session-logout-timeout').exists()).toBe(true) + }) + + describe('timers', () => { + it('has a token expires timer', () => { + expect(wrapper.vm.$options.timers).toEqual({ tokenExpires: expect.objectContaining({ + name: 'tokenExpires', + time: 15000, + repeat: true, + immediate: true, + autostart: true, + isSwitchTab: false, + })}) + }) + + describe('token is expired', () => { + beforeEach(() => { + mocks.$store.state.tokenTime = setTokenTime(-60) + wrapper = Wrapper() + }) + + it('emits logout', () => { + expect(wrapper.emitted('logout')).toBeTruthy() + }) + }) + + describe('token time less than 75 seconds', () => { + beforeEach(() => { + mocks.$store.state.tokenTime = setTokenTime(60) + jest.useFakeTimers() + wrapper = Wrapper() + spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') + spy.mockImplementation(() => Promise.resolve(true)) + }) + + it('sets the timer to 1000', () => { + expect(wrapper.vm.timers.tokenExpires.time).toBe(1000) + }) + + it.skip('opens the modal', () => { + jest.advanceTimersByTime(1000) + jest.advanceTimersByTime(1000) + jest.advanceTimersByTime(1000) + jest.advanceTimersByTime(1000) + // console.log(wrapper.html()) + expect(spy).toBeCalled() + }) + }) + }) + }) +}) diff --git a/frontend/src/components/SessionLogoutTimeout.spec.js b/frontend/src/components/SessionLogoutTimeout.spec.js index 2a2b107e7..0f5d21d36 100644 --- a/frontend/src/components/SessionLogoutTimeout.spec.js +++ b/frontend/src/components/SessionLogoutTimeout.spec.js @@ -5,14 +5,17 @@ const localVue = global.localVue const apolloQueryMock = jest.fn() -const state = { - token: '1234', - tokenTime: '123456789', +const setTokenTime = (seconds) => { + const now = new Date() + return Math.floor(new Date(now.setSeconds(now.getSeconds() + seconds)).getTime() / 1000) } const mocks = { $store: { - state, + state: { + token: '1234', + tokenTime: setTokenTime(120), + }, }, $i18n: { locale: 'en', @@ -29,7 +32,7 @@ const mocks = { } describe('SessionLogoutTimeout', () => { - let wrapper + let wrapper, spy const Wrapper = () => { return mount(SessionLogoutTimeout, { localVue, mocks }) @@ -37,11 +40,60 @@ describe('SessionLogoutTimeout', () => { describe('mount', () => { beforeEach(() => { + jest.clearAllMocks() wrapper = Wrapper() }) it('renders the component div.session-logout-timeout', () => { expect(wrapper.find('div.session-logout-timeout').exists()).toBe(true) }) + + describe('timers', () => { + it('has a token expires timer', () => { + expect(wrapper.vm.$options.timers).toEqual({ + tokenExpires: expect.objectContaining({ + name: 'tokenExpires', + time: 15000, + repeat: true, + immediate: true, + autostart: true, + isSwitchTab: false, + }), + }) + }) + + describe('token is expired', () => { + beforeEach(() => { + mocks.$store.state.tokenTime = setTokenTime(-60) + wrapper = Wrapper() + }) + + it('emits logout', () => { + expect(wrapper.emitted('logout')).toBeTruthy() + }) + }) + + describe('token time less than 75 seconds', () => { + beforeEach(() => { + mocks.$store.state.tokenTime = setTokenTime(60) + jest.useFakeTimers() + wrapper = Wrapper() + spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') + spy.mockImplementation(() => Promise.resolve(true)) + }) + + it('sets the timer to 1000', () => { + expect(wrapper.vm.timers.tokenExpires.time).toBe(1000) + }) + + it.skip('opens the modal', () => { + jest.advanceTimersByTime(1000) + jest.advanceTimersByTime(1000) + jest.advanceTimersByTime(1000) + jest.advanceTimersByTime(1000) + expect(spy).toBeCalled() + }) + }) + }) }) }) diff --git a/frontend/src/components/TransactionLinks/TransactionLink.spec.js b/frontend/src/components/TransactionLinks/TransactionLink.spec.js index ad9e4860e..13aaea900 100644 --- a/frontend/src/components/TransactionLinks/TransactionLink.spec.js +++ b/frontend/src/components/TransactionLinks/TransactionLink.spec.js @@ -92,6 +92,17 @@ describe('TransactionLink', () => { expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.link-copied') }) }) + + describe('copy with error', () => { + beforeEach(async () => { + navigatorClipboardMock.mockRejectedValue() + await wrapper.find('.test-copy-link .dropdown-item').trigger('click') + }) + + it('toasts an error', () => { + expect(toastErrorSpy).toBeCalledWith('gdd_per_link.not-copied') + }) + }) }) describe('qr code modal', () => { diff --git a/frontend/src/layouts/AuthLayout.spec.js b/frontend/src/layouts/AuthLayout.spec.js index 2246793d5..30c858ea5 100644 --- a/frontend/src/layouts/AuthLayout.spec.js +++ b/frontend/src/layouts/AuthLayout.spec.js @@ -35,9 +35,10 @@ describe('AuthLayout', () => { beforeEach(() => { wrapper = Wrapper() }) + describe('Mobile Version Start', () => { beforeEach(() => { - wrapper.vm.mobileStart = true + wrapper.findComponent({ name: 'AuthMobileStart' }).vm.$emit('set-mobile-start', true) }) it('has Component AuthMobileStart', () => { diff --git a/frontend/test/testSetup.js b/frontend/test/testSetup.js index 614621a09..32cf335a8 100644 --- a/frontend/test/testSetup.js +++ b/frontend/test/testSetup.js @@ -8,6 +8,7 @@ import * as rules from 'vee-validate/dist/rules' import { messages } from 'vee-validate/dist/locale/en.json' import RegeneratorRuntime from 'regenerator-runtime' +import VueTimers from 'vue-timers' import VueMoment from 'vue-moment' @@ -46,6 +47,7 @@ global.localVue.use(Vuex) global.localVue.use(IconsPlugin) global.localVue.use(RegeneratorRuntime) global.localVue.use(VueMoment) +global.localVue.use(VueTimers) global.localVue.component('validation-provider', ValidationProvider) global.localVue.component('validation-observer', ValidationObserver) // global.localVue.directive('click-outside', clickOutside)