import { mount, RouterLinkStub } from '@vue/test-utils' import flushPromises from 'flush-promises' import DashboardLayout from './DashboardLayout' import { toastErrorSpy } from '@test/testSetup' jest.useFakeTimers() const localVue = global.localVue const storeDispatchMock = jest.fn() const apolloQueryMock = jest.fn() const apolloMutationMock = jest.fn() const routerPushMock = jest.fn() const stubs = { RouterLink: RouterLinkStub, RouterView: true, LastTransactions: true, } const mocks = { $t: jest.fn((t) => t), $d: jest.fn((d) => d), $apollo: { query: apolloQueryMock, mutate: apolloMutationMock, }, $n: jest.fn(), $route: { meta: { hideFooter: false, }, path: { replace: jest.fn(), }, }, $router: { push: routerPushMock, currentRoute: { path: '/overview', }, }, $store: { dispatch: storeDispatchMock, state: { email: 'user@example.org', publisherId: 123, firstName: 'User', lastName: 'Example', token: 'valid-token', }, }, $i18n: { locale: 'en', }, } describe('DashboardLayout', () => { let wrapper const Wrapper = () => { return mount(DashboardLayout, { localVue, mocks, stubs }) } describe('mount', () => { beforeEach(() => { apolloQueryMock.mockResolvedValue({ data: { communityStatistics: { totalUsers: 3113, activeUsers: 1057, deletedUsers: 35, totalGradidoCreated: '4083774.05000000000000000000', totalGradidoDecayed: '-1062639.13634129622923372197', totalGradidoAvailable: '2513565.869444365732411569', totalGradidoUnbookedDecayed: '-500474.6738366222166261272', }, }, }) wrapper = Wrapper() }) it('renders DIV .main-page', () => { expect(wrapper.find('div.main-page').exists()).toBe(true) }) describe('at first', () => { it('renders a component Skeleton', () => { expect(wrapper.findComponent({ name: 'SkeletonOverview' }).exists()).toBe(true) }) }) describe('after a timeout', () => { beforeEach(() => { jest.advanceTimersByTime(1500) }) describe('update transactions', () => { beforeEach(async () => { await apolloQueryMock.mockResolvedValue({ data: { transactionList: { balance: { balanceGDT: 100, count: 4, linkCount: 8, balance: 1450, decay: 1250, }, transactions: ['transaction', 'transaction', 'transaction', 'transaction'], }, }, }) await wrapper .findComponent({ ref: 'router-view' }) .vm.$emit('update-transactions', { currentPage: 2, pageSize: 5 }) await flushPromises() }) it('calls the API', () => { expect(apolloQueryMock).toBeCalledWith( expect.objectContaining({ variables: { currentPage: 2, pageSize: 5, }, }), ) }) it('updates balance', () => { expect(wrapper.vm.balance).toBe(1450) }) it('updates transactions', () => { expect(wrapper.vm.transactions).toEqual([ 'transaction', 'transaction', 'transaction', 'transaction', ]) }) it('updates GDT balance', () => { expect(wrapper.vm.GdtBalance).toBe(100) }) it('updates transaction count', () => { expect(wrapper.vm.transactionCount).toBe(4) }) it('updates transaction link count', () => { expect(wrapper.vm.transactionLinkCount).toBe(8) }) }) describe('update transactions returns error', () => { beforeEach(async () => { apolloQueryMock.mockRejectedValue({ message: 'Ouch!', }) await wrapper .findComponent({ ref: 'router-view' }) .vm.$emit('update-transactions', { currentPage: 2, pageSize: 5 }) await flushPromises() }) it('sets pending to true', () => { expect(wrapper.vm.pending).toBeTruthy() }) it('toasts the error message', () => { expect(toastErrorSpy).toBeCalledWith('Ouch!') }) }) describe('set tunneled email', () => { it('updates tunneled email', async () => { await wrapper .findComponent({ ref: 'router-view' }) .vm.$emit('set-tunneled-email', 'bibi@bloxberg.de') expect(wrapper.vm.tunneledEmail).toBe('bibi@bloxberg.de') }) }) it('has a component Navbar', () => { expect(wrapper.findComponent({ name: 'Navbar' }).exists()).toBe(true) }) it('has a navbar', () => { expect(wrapper.find('.main-navbar').exists()).toBe(true) }) it('has a sidebar', () => { expect(wrapper.find('.main-sidebar').exists()).toBeTruthy() }) it('has a main content div', () => { expect(wrapper.find('div.main-content').exists()).toBeTruthy() }) it('has a footer inside the main content', () => { expect(wrapper.find('div.main-page').find('footer.footer').exists()).toBeTruthy() }) describe('navigation bar', () => { describe('logout', () => { beforeEach(async () => { await apolloMutationMock.mockResolvedValue({ data: { logout: 'success', }, }) await wrapper.findComponent({ name: 'Sidebar' }).vm.$emit('logout') await flushPromises() await wrapper.vm.$nextTick() }) it('calls the API', async () => { await expect(apolloMutationMock).toBeCalled() }) it('dispatches logout to store', () => { expect(storeDispatchMock).toBeCalledWith('logout') }) it('redirects to login page', () => { expect(routerPushMock).toBeCalledWith('/login') }) }) describe('logout fails', () => { beforeEach(async () => { apolloMutationMock.mockRejectedValue({ message: 'error', }) await wrapper.findComponent({ name: 'sidebar' }).vm.$emit('logout') await flushPromises() }) it('dispatches logout to store', () => { expect(storeDispatchMock).toBeCalledWith('logout') }) it('redirects to login page', () => { expect(routerPushMock).toBeCalledWith('/login') }) describe('redirect to login already done', () => { beforeEach(() => { mocks.$router.currentRoute.path = '/login' jest.resetAllMocks() }) it('does not call the redirect to login', () => { expect(routerPushMock).not.toBeCalled() }) }) }) }) describe.skip('set visible method', () => { beforeEach(() => { wrapper.findComponent({ name: 'NavbarNew' }).vm.$emit('set-visible', true) }) it('sets visible to true', () => { expect(wrapper.vm.visible).toBe(true) }) }) describe.skip('elopage URI', () => { describe('user has no publisher ID and no elopage', () => { beforeEach(() => { mocks.$store.state.publisherId = null mocks.$store.state.hasElopage = false wrapper = Wrapper() }) it('links to basic-de', () => { expect(wrapper.vm.elopageUri).toBe( 'https://elopage.com/s/gradido/basic-de/payment?locale=en&prid=111&pid=2896&firstName=User&lastName=Example&email=user@example.org', ) }) }) describe('user has elopage', () => { beforeEach(() => { mocks.$store.state.publisherId = '123' mocks.$store.state.hasElopage = true wrapper = Wrapper() }) it('links to sign in for elopage', () => { expect(wrapper.vm.elopageUri).toBe('https://elopage.com/s/gradido/sign_in?locale=en') }) }) }) describe.skip('admin method', () => { const windowLocationMock = jest.fn() beforeEach(() => { delete window.location window.location = { assign: windowLocationMock, } wrapper.findComponent({ name: 'NavbarNew' }).vm.$emit('admin') }) it('dispatches logout to store', () => { expect(storeDispatchMock).toBeCalled() }) it('changes window location to admin interface', () => { expect(windowLocationMock).toBeCalledWith( 'http://localhost/admin/authenticate?token=valid-token', ) }) }) }) }) })