mirror of
https://github.com/IT4Change/gradido.git
synced 2026-03-29 13:45:35 +00:00
320 lines
8.1 KiB
JavaScript
320 lines
8.1 KiB
JavaScript
import { mount } from '@vue/test-utils'
|
|
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'
|
|
import { nextTick, ref } from 'vue'
|
|
import DashboardLayout from './DashboardLayout'
|
|
import { createStore } from 'vuex'
|
|
import { createRouter, createWebHistory } from 'vue-router'
|
|
import routes from '@/routes/routes'
|
|
import { useQuery } from '@vue/apollo-composable'
|
|
|
|
const toastErrorSpy = vi.fn()
|
|
|
|
vi.mock('@/composables/useToast', () => ({
|
|
useAppToast: () => ({
|
|
toastError: toastErrorSpy,
|
|
}),
|
|
}))
|
|
|
|
const mockRefetchFn = vi.fn()
|
|
const mockMutateFn = vi.fn()
|
|
let onErrorHandler
|
|
let onResultHandler
|
|
const mockQueryResult = ref(null)
|
|
const loading = ref(false)
|
|
|
|
vi.mock('@vue/apollo-composable', () => ({
|
|
useQuery: vi.fn(() => ({
|
|
refetch: mockRefetchFn,
|
|
result: mockQueryResult,
|
|
onResult: (handler) => {
|
|
onResultHandler = handler
|
|
},
|
|
onError: (handler) => {
|
|
onErrorHandler = handler
|
|
},
|
|
loading,
|
|
})),
|
|
useLazyQuery: vi.fn(() => ({
|
|
refetch: mockRefetchFn,
|
|
result: mockQueryResult,
|
|
onResult: (handler) => {
|
|
onResultHandler = handler
|
|
},
|
|
onError: (handler) => {
|
|
onErrorHandler = handler
|
|
},
|
|
loading,
|
|
})),
|
|
useMutation: vi.fn(() => ({
|
|
mutate: mockMutateFn,
|
|
onDone: vi.fn(),
|
|
onError: vi.fn(),
|
|
})),
|
|
}))
|
|
|
|
vi.mock('vue-i18n', () => ({
|
|
useI18n: () => ({
|
|
t: (key) => key,
|
|
d: (value) => value,
|
|
n: (value) => value,
|
|
}),
|
|
}))
|
|
|
|
const router = createRouter({
|
|
history: createWebHistory(),
|
|
routes,
|
|
})
|
|
|
|
describe('DashboardLayout', () => {
|
|
let wrapper
|
|
let store
|
|
let logoutSpy
|
|
let routerPushSpy
|
|
|
|
const createVuexStore = () => {
|
|
logoutSpy = vi.fn()
|
|
return createStore({
|
|
state: {
|
|
publisherId: 123,
|
|
firstName: 'User',
|
|
lastName: 'Example',
|
|
token: 'valid-token',
|
|
roles: [],
|
|
},
|
|
actions: {
|
|
logout: logoutSpy,
|
|
},
|
|
})
|
|
}
|
|
|
|
const createWrapper = () => {
|
|
store = createVuexStore()
|
|
routerPushSpy = vi.spyOn(router, 'push')
|
|
return mount(DashboardLayout, {
|
|
global: {
|
|
plugins: [store, router],
|
|
stubs: {
|
|
RouterLink: true,
|
|
RouterView: true,
|
|
LastTransactions: true,
|
|
Navbar: true,
|
|
Sidebar: true,
|
|
MobileSidebar: true,
|
|
Breadcrumb: true,
|
|
ContentHeader: true,
|
|
RightSide: true,
|
|
ContentFooter: true,
|
|
SkeletonOverview: true,
|
|
'fade-transition': true,
|
|
},
|
|
mocks: {
|
|
$t: (key) => key,
|
|
$d: (d) => d,
|
|
$n: vi.fn(),
|
|
$i18n: {
|
|
locale: 'en',
|
|
},
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.useFakeTimers()
|
|
wrapper = createWrapper()
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.clearAllMocks()
|
|
vi.clearAllTimers()
|
|
})
|
|
|
|
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(async () => {
|
|
vi.advanceTimersByTime(1500)
|
|
loading.value = false
|
|
await nextTick()
|
|
})
|
|
|
|
describe('update transactions', () => {
|
|
beforeEach(async () => {
|
|
onResultHandler({
|
|
data: {
|
|
transactionList: {
|
|
balance: {
|
|
balanceGDT: '100',
|
|
count: 4,
|
|
linkCount: 8,
|
|
balance: '1450',
|
|
},
|
|
transactions: ['transaction1', 'transaction2', 'transaction3', 'transaction4'],
|
|
},
|
|
},
|
|
})
|
|
|
|
await wrapper.vm.updateTransactions({ currentPage: 2, pageSize: 5 })
|
|
await nextTick() // Ensure all promises are resolved
|
|
})
|
|
|
|
it('load call to the API', () => {
|
|
expect(useQuery).toHaveBeenCalled()
|
|
})
|
|
|
|
it('updates balance', () => {
|
|
expect(wrapper.vm.balance).toBe(1450)
|
|
})
|
|
|
|
it('updates transactions', () => {
|
|
expect(wrapper.vm.transactions).toEqual([
|
|
'transaction1',
|
|
'transaction2',
|
|
'transaction3',
|
|
'transaction4',
|
|
])
|
|
})
|
|
|
|
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 () => {
|
|
wrapper.vm.skeleton = false
|
|
await wrapper
|
|
.findComponent({ ref: 'router-view' })
|
|
.vm.$emit('update-transactions', { currentPage: 2, pageSize: 5 })
|
|
await nextTick()
|
|
})
|
|
|
|
it('sets pending to true', () => {
|
|
expect(wrapper.vm.pending).toBeTruthy()
|
|
})
|
|
|
|
it('toasts the error message', () => {
|
|
onErrorHandler({ message: 'Ouch!' })
|
|
expect(toastErrorSpy).toHaveBeenCalledWith('Ouch!')
|
|
})
|
|
})
|
|
|
|
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 () => {
|
|
mockMutateFn.mockResolvedValue({ logout: 'success' })
|
|
await wrapper.findComponent({ name: 'Sidebar' }).vm.$emit('logout')
|
|
await nextTick()
|
|
})
|
|
|
|
it('calls the API', () => {
|
|
expect(mockMutateFn).toHaveBeenCalled()
|
|
})
|
|
|
|
it('dispatches logout to store', () => {
|
|
expect(logoutSpy).toHaveBeenCalled()
|
|
})
|
|
|
|
it('redirects to login page', () => {
|
|
expect(routerPushSpy).toHaveBeenCalledWith('/login')
|
|
})
|
|
})
|
|
|
|
describe('logout fails', () => {
|
|
beforeEach(async () => {
|
|
mockMutateFn.mockRejectedValue(new Error('error'))
|
|
await wrapper.findComponent({ name: 'Sidebar' }).vm.$emit('logout')
|
|
await nextTick()
|
|
})
|
|
|
|
it('dispatches logout to store', () => {
|
|
expect(logoutSpy).toHaveBeenCalled()
|
|
})
|
|
|
|
it('redirects to login page', () => {
|
|
expect(routerPushSpy).toHaveBeenCalledWith('/login')
|
|
})
|
|
|
|
describe('redirect to login already done', () => {
|
|
beforeEach(async () => {
|
|
await router.push('/login')
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
it('does not call the redirect to login', async () => {
|
|
const routerPushSpy = vi.spyOn(router, 'push')
|
|
await wrapper.findComponent({ name: 'Sidebar' }).vm.$emit('logout')
|
|
await nextTick()
|
|
expect(routerPushSpy).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe.skip('set visible method', () => {
|
|
beforeEach(async () => {
|
|
await wrapper.findComponent({ name: 'NavbarNew' }).vm.$emit('set-visible', true)
|
|
})
|
|
|
|
it('sets visible to true', () => {
|
|
expect(wrapper.vm.visible).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe.skip('admin method', () => {
|
|
const windowLocationMock = vi.fn()
|
|
beforeEach(() => {
|
|
delete window.location
|
|
window.location = { assign: windowLocationMock }
|
|
wrapper.findComponent({ name: 'NavbarNew' }).vm.$emit('admin')
|
|
})
|
|
|
|
it('dispatches logout to store', () => {
|
|
expect(store.dispatch).toHaveBeenCalledWith('logout')
|
|
})
|
|
|
|
it('changes window location to admin interface', () => {
|
|
expect(windowLocationMock).toHaveBeenCalledWith(
|
|
'http://localhost/admin/authenticate?token=valid-token',
|
|
)
|
|
})
|
|
})
|
|
})
|
|
})
|