mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
fix frontend test, decouple some more
This commit is contained in:
parent
720283d8fe
commit
b8fd965f50
@ -52,7 +52,7 @@ describe('ContributionMessagesFormular', () => {
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
mockMutate.mockResolvedValue({})
|
||||
mockMutate.mockResolvedValue({ data: { createContributionMessage: {} } })
|
||||
wrapper = createWrapper()
|
||||
})
|
||||
|
||||
@ -66,7 +66,7 @@ describe('ContributionMessagesFormular', () => {
|
||||
|
||||
it('resets the form on reset event', async () => {
|
||||
await wrapper.find('form').trigger('reset')
|
||||
expect(wrapper.vm.form.text).toBe('')
|
||||
expect(wrapper.vm.formText).toBe('')
|
||||
})
|
||||
|
||||
describe('form submission', () => {
|
||||
@ -82,19 +82,14 @@ describe('ContributionMessagesFormular', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('emits get-list-contribution-messages event', async () => {
|
||||
it('emits add-contribution-message event', async () => {
|
||||
await nextTick()
|
||||
expect(wrapper.emitted('get-list-contribution-messages')).toEqual([[false]])
|
||||
})
|
||||
|
||||
it('emits update-status event', async () => {
|
||||
await nextTick()
|
||||
expect(wrapper.emitted('update-status')).toEqual([[42]])
|
||||
expect(wrapper.emitted('add-contribution-message')).toEqual([[{}]])
|
||||
})
|
||||
|
||||
it('resets the form text', async () => {
|
||||
await nextTick()
|
||||
expect(wrapper.vm.form.text).toBe('')
|
||||
expect(wrapper.vm.formText).toBe('')
|
||||
})
|
||||
|
||||
it('shows success toast', async () => {
|
||||
|
||||
@ -77,16 +77,4 @@ describe('ContributionMessagesList', () => {
|
||||
expect(wrapper.find('button').text()).toContain('form.close')
|
||||
})
|
||||
})
|
||||
|
||||
describe('events', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapper()
|
||||
})
|
||||
|
||||
it('emits update-status event when updateStatus method is called', async () => {
|
||||
await wrapper.vm.updateStatus(42)
|
||||
expect(wrapper.emitted('update-status')).toBeTruthy()
|
||||
expect(wrapper.emitted('update-status')[0]).toEqual([42])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import ContributionForm from './ContributionForm.vue'
|
||||
import { useForm } from 'vee-validate'
|
||||
|
||||
// Mock external components and dependencies
|
||||
vi.mock('@/components/Inputs/InputAmount', () => ({
|
||||
@ -37,12 +36,16 @@ vi.mock('vee-validate', () => ({
|
||||
})),
|
||||
}))
|
||||
|
||||
const global = {
|
||||
stubs: ['BForm', 'BFormInput', 'BRow', 'BCol', 'BButton'],
|
||||
}
|
||||
|
||||
describe('ContributionForm', () => {
|
||||
let wrapper
|
||||
|
||||
const defaultProps = {
|
||||
modelValue: {
|
||||
date: '2024-09-12',
|
||||
contributionDate: '2024-09-12',
|
||||
memo: 'Test memo',
|
||||
hours: 2,
|
||||
amount: 40,
|
||||
@ -51,12 +54,26 @@ describe('ContributionForm', () => {
|
||||
maxGddThisMonth: 200,
|
||||
}
|
||||
|
||||
const createWrapperWithDate = (date) => {
|
||||
return mount(ContributionForm, {
|
||||
props: {
|
||||
...defaultProps,
|
||||
modelValue: {
|
||||
...defaultProps.modelValue,
|
||||
contributionDate: date.toISOString(),
|
||||
},
|
||||
},
|
||||
global,
|
||||
})
|
||||
}
|
||||
const thisMonth = new Date()
|
||||
const lastMonth = new Date()
|
||||
lastMonth.setMonth(lastMonth.getMonth() - 1, 1)
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = mount(ContributionForm, {
|
||||
props: defaultProps,
|
||||
global: {
|
||||
stubs: ['BForm', 'BFormInput', 'BRow', 'BCol', 'BButton'],
|
||||
},
|
||||
global,
|
||||
})
|
||||
})
|
||||
|
||||
@ -65,19 +82,17 @@ describe('ContributionForm', () => {
|
||||
})
|
||||
|
||||
describe('compute isThisMonth', () => {
|
||||
it('return true', async () => {
|
||||
await wrapper.setProps({
|
||||
modelValue: { date: new Date().toISOString() },
|
||||
})
|
||||
expect(wrapper.vm.isThisMonth).toBe(true)
|
||||
})
|
||||
it('return false', async () => {
|
||||
const now = new Date()
|
||||
const lastMonth = new Date(now.setMonth(now.getMonth() - 1, 1))
|
||||
await wrapper.setProps({
|
||||
modelValue: { date: lastMonth.toISOString() },
|
||||
})
|
||||
expect(wrapper.vm.isThisMonth).toBe(false)
|
||||
it.each([
|
||||
[thisMonth, true, 'should return true for current month'],
|
||||
[lastMonth, false, 'should return false for last month'],
|
||||
[
|
||||
new Date(new Date().setFullYear(new Date().getFullYear() + 1)),
|
||||
false,
|
||||
'should return false for next year',
|
||||
],
|
||||
])('%s => %s (%s)', (date, expected, desc) => {
|
||||
const wrapper = createWrapperWithDate(date)
|
||||
expect(wrapper.vm.isThisMonth).toBe(expected)
|
||||
})
|
||||
})
|
||||
|
||||
@ -85,21 +100,39 @@ describe('ContributionForm', () => {
|
||||
it('if both max gdd are > 0', () => {
|
||||
expect(wrapper.vm.noOpenCreation).toBeUndefined()
|
||||
})
|
||||
it('if max gdd for this month is 0, and form.date is in last month', async () => {
|
||||
const now = new Date()
|
||||
const lastMonth = new Date(now.setMonth(now.getMonth() - 1, 1))
|
||||
await wrapper.setProps({
|
||||
maxGddThisMonth: 0,
|
||||
modelValue: { date: lastMonth.toISOString() },
|
||||
describe('if form.date is in last month', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapperWithDate(lastMonth)
|
||||
})
|
||||
it('if max gdd for this month is 0', async () => {
|
||||
await wrapper.setProps({
|
||||
maxGddThisMonth: 0,
|
||||
})
|
||||
expect(wrapper.vm.noOpenCreation).toBeUndefined()
|
||||
})
|
||||
it('if max gdd last month is 0', async () => {
|
||||
await wrapper.setProps({
|
||||
maxGddLastMonth: 0,
|
||||
})
|
||||
expect(wrapper.vm.noOpenCreation).toBe('contribution.noOpenCreation.lastMonth')
|
||||
})
|
||||
expect(wrapper.vm.noOpenCreation).toBeUndefined()
|
||||
})
|
||||
it('if max gdd for last month is 0, and form.date is in this month', async () => {
|
||||
await wrapper.setProps({
|
||||
maxGddLastMonth: 0,
|
||||
modelValue: { date: new Date().toISOString() },
|
||||
describe('if form.date is in this month', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapperWithDate(thisMonth)
|
||||
})
|
||||
it('if max gdd for last month is 0', async () => {
|
||||
await wrapper.setProps({
|
||||
maxGddLastMonth: 0,
|
||||
})
|
||||
expect(wrapper.vm.noOpenCreation).toBeUndefined()
|
||||
})
|
||||
it('if max gdd this month is 0', async () => {
|
||||
await wrapper.setProps({
|
||||
maxGddThisMonth: 0,
|
||||
})
|
||||
expect(wrapper.vm.noOpenCreation).toBe('contribution.noOpenCreation.thisMonth')
|
||||
})
|
||||
expect(wrapper.vm.noOpenCreation).toBeUndefined()
|
||||
})
|
||||
it('if max gdd is 0 for both months', async () => {
|
||||
await wrapper.setProps({
|
||||
@ -108,30 +141,12 @@ describe('ContributionForm', () => {
|
||||
})
|
||||
expect(wrapper.vm.noOpenCreation).toBe('contribution.noOpenCreation.allMonth')
|
||||
})
|
||||
it('if max gdd this month is zero and form.date is inside this month', async () => {
|
||||
await wrapper.setProps({
|
||||
maxGddThisMonth: 0,
|
||||
modelValue: { date: new Date().toISOString() },
|
||||
})
|
||||
expect(wrapper.vm.noOpenCreation).toBe('contribution.noOpenCreation.thisMonth')
|
||||
})
|
||||
it('if max gdd last month is zero and form.date is inside last month', async () => {
|
||||
const now = new Date()
|
||||
const lastMonth = new Date(now.setMonth(now.getMonth() - 1, 1))
|
||||
await wrapper.setProps({
|
||||
maxGddLastMonth: 0,
|
||||
modelValue: { date: lastMonth.toISOString() },
|
||||
})
|
||||
expect(wrapper.vm.noOpenCreation).toBe('contribution.noOpenCreation.lastMonth')
|
||||
})
|
||||
})
|
||||
|
||||
it('computes disabled correctly', async () => {
|
||||
expect(wrapper.vm.disabled).toBe(true)
|
||||
|
||||
await wrapper.setProps({
|
||||
modelValue: { date: new Date().toISOString().slice(0, 10) },
|
||||
})
|
||||
wrapper = createWrapperWithDate(thisMonth)
|
||||
|
||||
wrapper.vm.form.amount = 100
|
||||
|
||||
@ -154,7 +169,7 @@ describe('ContributionForm', () => {
|
||||
expect(wrapper.vm.form.amount).toBe('60.00')
|
||||
})
|
||||
|
||||
it('emits update-contribution event on submit for existing contribution', async () => {
|
||||
it('emits upsert-contribution event on submit for existing contribution', async () => {
|
||||
const existingContribution = {
|
||||
...defaultProps.modelValue,
|
||||
id: '123',
|
||||
@ -174,17 +189,17 @@ describe('ContributionForm', () => {
|
||||
|
||||
wrapper.vm.submit()
|
||||
|
||||
expect(wrapper.emitted('update-contribution')).toBeTruthy()
|
||||
expect(wrapper.emitted('update-contribution')[0][0]).toEqual(
|
||||
expect(wrapper.emitted('upsert-contribution')).toBeTruthy()
|
||||
expect(wrapper.emitted('upsert-contribution')[0][0]).toEqual(
|
||||
expect.objectContaining({
|
||||
id: '123',
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('emits set-contribution event on submit for new contribution', async () => {
|
||||
it('emits upsert-contribution event on submit for new contribution', async () => {
|
||||
wrapper.vm.submit()
|
||||
|
||||
expect(wrapper.emitted('set-contribution')).toBeTruthy()
|
||||
expect(wrapper.emitted('upsert-contribution')).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
@ -85,11 +85,12 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, computed, watch, ref, onMounted, onUnmounted, toRaw } from 'vue'
|
||||
import { reactive, computed, ref, onMounted, onUnmounted, toRaw } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import ValidatedInput from '@/components/Inputs/ValidatedInput'
|
||||
import LabeledInput from '@/components/Inputs/LabeledInput'
|
||||
import { memo as memoSchema } from '@/validationSchemas'
|
||||
import OpenCreationsAmount from './OpenCreationsAmount.vue'
|
||||
import { object, date as dateSchema, number } from 'yup'
|
||||
import { GDD_PER_HOUR } from '../../constants'
|
||||
|
||||
|
||||
@ -1,14 +1,24 @@
|
||||
import { listAllContributions, listContributions } from '@/graphql/contributions.graphql'
|
||||
import { useQuery } from '@vue/apollo-composable'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import ContributionList from './ContributionList'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
messages: {
|
||||
en: {
|
||||
contribution: {
|
||||
noContributions: {
|
||||
myContributions: 'No contributions',
|
||||
emptyPage: 'No contributions',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const router = createRouter({
|
||||
@ -53,93 +63,53 @@ describe('ContributionList', () => {
|
||||
},
|
||||
}
|
||||
|
||||
const contributions = {
|
||||
contributionCount: 3,
|
||||
listContributions: [
|
||||
{
|
||||
id: 0,
|
||||
date: '07/06/2022',
|
||||
memo: 'Ich habe 10 Stunden die Elbwiesen von Müll befreit.',
|
||||
amount: '200',
|
||||
status: 'IN_PROGRESS',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
date: '06/22/2022',
|
||||
memo: 'Ich habe 30 Stunden Frau Müller beim Einkaufen und im Haushalt geholfen.',
|
||||
amount: '600',
|
||||
status: 'CONFIRMED',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
date: '05/04/2022',
|
||||
memo: 'Ich habe 50 Stunden den Nachbarkindern bei ihren Hausaufgaben geholfen und Nachhilfeunterricht gegeben.',
|
||||
amount: '1000',
|
||||
status: 'DENIED',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const propsData = {
|
||||
allContribution: false,
|
||||
emptyText: '',
|
||||
}
|
||||
|
||||
const allContributions = {
|
||||
contributionCount: 3,
|
||||
listAllContributions: [
|
||||
{
|
||||
id: 0,
|
||||
date: '07/06/2022',
|
||||
memo: 'Ich habe 10 Stunden die Elbwiesen von Müll befreit.',
|
||||
amount: '200',
|
||||
status: 'IN_PROGRESS',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
date: '06/22/2022',
|
||||
memo: 'Ich habe 30 Stunden Frau Müller beim Einkaufen und im Haushalt geholfen.',
|
||||
amount: '600',
|
||||
status: 'CONFIRMED',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
date: '05/04/2022',
|
||||
memo: 'Ich habe 50 Stunden den Nachbarkindern bei ihren Hausaufgaben geholfen und Nachhilfeunterricht gegeben.',
|
||||
amount: '1000',
|
||||
status: 'DENIED',
|
||||
},
|
||||
],
|
||||
}
|
||||
const contributions = ref({
|
||||
listContributions: {
|
||||
contributionCount: 3,
|
||||
contributionList: [
|
||||
{
|
||||
id: 0,
|
||||
date: '07/06/2022',
|
||||
memo: 'Ich habe 10 Stunden die Elbwiesen von Müll befreit.',
|
||||
amount: '200',
|
||||
status: 'IN_PROGRESS',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
date: '06/22/2022',
|
||||
memo: 'Ich habe 30 Stunden Frau Müller beim Einkaufen und im Haushalt geholfen.',
|
||||
amount: '600',
|
||||
status: 'CONFIRMED',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
date: '05/04/2022',
|
||||
memo: 'Ich habe 50 Stunden den Nachbarkindern bei ihren Hausaufgaben geholfen und Nachhilfeunterricht gegeben.',
|
||||
amount: '1000',
|
||||
status: 'DENIED',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
const mountWrapper = () => {
|
||||
return mount(ContributionList, {
|
||||
propsData,
|
||||
global,
|
||||
})
|
||||
}
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
describe('mount', () => {
|
||||
const mockListContributionsQuery = vi.fn()
|
||||
const mockListAllContributionsQuery = vi.fn()
|
||||
|
||||
beforeEach(() => {
|
||||
vi.mocked(useQuery).mockImplementation((query) => {
|
||||
if (query === listContributions) {
|
||||
return {
|
||||
result: contributions,
|
||||
loading: vi.fn(),
|
||||
onResult: mockListContributionsQuery,
|
||||
refetch: vi.fn(),
|
||||
}
|
||||
}
|
||||
if (query === listAllContributions) {
|
||||
return {
|
||||
result: allContributions,
|
||||
loading: vi.fn(),
|
||||
onResult: mockListAllContributionsQuery,
|
||||
refetch: vi.fn(),
|
||||
}
|
||||
return {
|
||||
result: contributions,
|
||||
loading,
|
||||
onResult: mockListContributionsQuery,
|
||||
refetch: vi.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
@ -151,23 +121,11 @@ describe('ContributionList', () => {
|
||||
})
|
||||
|
||||
describe('mount as user contributions list', () => {
|
||||
beforeEach(() => {
|
||||
propsData.allContribution = false
|
||||
})
|
||||
it('fetches initial data', () => {
|
||||
expect(mockListContributionsQuery).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('mount as all contributions list', () => {
|
||||
beforeEach(() => {
|
||||
propsData.allContribution = true
|
||||
})
|
||||
it('fetches initial data', () => {
|
||||
expect(mockListAllContributionsQuery).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
it('has a DIV .contribution-list', () => {
|
||||
expect(wrapper.find('div.contribution-list').exists()).toBe(true)
|
||||
})
|
||||
@ -181,8 +139,7 @@ describe('ContributionList', () => {
|
||||
|
||||
describe('list count greater than page size', () => {
|
||||
beforeEach(async () => {
|
||||
contributions.contributionCount = 33
|
||||
// await wrapper.setProps({ contributionCount: 33 })
|
||||
contributions.value.listContributions.contributionCount = 33
|
||||
})
|
||||
|
||||
it('has pagination buttons', () => {
|
||||
@ -195,18 +152,17 @@ describe('ContributionList', () => {
|
||||
window.scrollTo = scrollToMock
|
||||
|
||||
beforeEach(async () => {
|
||||
contributions.contributionCount = 33
|
||||
// await wrapper.setProps({ contributionCount: 33 })
|
||||
await wrapper.findComponent({ name: 'BPagination' }).vm.$emit('update:modelValue', 2)
|
||||
contributions.value.listContributions.contributionCount = 33
|
||||
await wrapper
|
||||
.findComponent({ name: 'PaginatorRouteParamsPage' })
|
||||
.vm.$emit('update:modelValue', 2)
|
||||
})
|
||||
|
||||
it('emits update contribution list', () => {
|
||||
expect(wrapper.emitted('update-list-contributions')).toEqual([
|
||||
[{ currentPage: 2, pageSize: 25 }],
|
||||
])
|
||||
it('updates current page', () => {
|
||||
expect(wrapper.vm.currentPage).toBe(2)
|
||||
})
|
||||
|
||||
it('scrolls to top', () => {
|
||||
it.skip('scrolls to top', () => {
|
||||
expect(scrollToMock).toHaveBeenCalledWith(0, 0)
|
||||
})
|
||||
})
|
||||
@ -220,31 +176,7 @@ describe('ContributionList', () => {
|
||||
})
|
||||
|
||||
it('emits update contribution form', () => {
|
||||
expect(wrapper.emitted('update-contribution-form')).toEqual([['item']])
|
||||
})
|
||||
})
|
||||
|
||||
describe('delete contribution', () => {
|
||||
beforeEach(async () => {
|
||||
await wrapper
|
||||
.findComponent({ name: 'ContributionListItem' })
|
||||
.vm.$emit('delete-contribution', { id: 2 })
|
||||
})
|
||||
|
||||
it('emits delete contribution', () => {
|
||||
expect(wrapper.emitted('delete-contribution')).toEqual([[{ id: 2 }]])
|
||||
})
|
||||
})
|
||||
|
||||
describe('update status', () => {
|
||||
beforeEach(async () => {
|
||||
await wrapper
|
||||
.findComponent({ name: 'ContributionListItem' })
|
||||
.vm.$emit('update-status', { id: 2 })
|
||||
})
|
||||
|
||||
it('emits update status', () => {
|
||||
expect(wrapper.emitted('update-status')).toEqual([[{ id: 2 }]])
|
||||
expect(wrapper.emitted('update-contribution-form')).toEqual([[{ item: 'item', page: 1 }]])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -0,0 +1,158 @@
|
||||
import { listAllContributions } from '@/graphql/contributions.graphql'
|
||||
import { useQuery } from '@vue/apollo-composable'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import ContributionListAll from './ContributionListAll.vue'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
})
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: { template: '<div>Home</div>' },
|
||||
},
|
||||
{
|
||||
path: '/test',
|
||||
name: 'test',
|
||||
component: ContributionListAll,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
vi.mock('@/components/Contributions/ContributionListAllItem.vue', () => ({
|
||||
default: {
|
||||
name: 'ContributionListAllItem',
|
||||
template: '<div></div>',
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@vue/apollo-composable', () => ({
|
||||
useQuery: vi.fn(),
|
||||
}))
|
||||
|
||||
describe('ContributionListAll', () => {
|
||||
let wrapper
|
||||
|
||||
const global = {
|
||||
plugins: [i18n, router],
|
||||
mocks: {
|
||||
$filters: {
|
||||
GDD: vi.fn((val) => val),
|
||||
},
|
||||
},
|
||||
stubs: {
|
||||
BPagination: true,
|
||||
},
|
||||
}
|
||||
|
||||
const allContributions = ref({
|
||||
listAllContributions: {
|
||||
contributionCount: 3,
|
||||
contributionList: [
|
||||
{
|
||||
id: 0,
|
||||
date: '07/06/2022',
|
||||
memo: 'Ich habe 10 Stunden die Elbwiesen von Müll befreit.',
|
||||
amount: '200',
|
||||
status: 'IN_PROGRESS',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
date: '06/22/2022',
|
||||
memo: 'Ich habe 30 Stunden Frau Müller beim Einkaufen und im Haushalt geholfen.',
|
||||
amount: '600',
|
||||
status: 'CONFIRMED',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
date: '05/04/2022',
|
||||
memo: 'Ich habe 50 Stunden den Nachbarkindern bei ihren Hausaufgaben geholfen und Nachhilfeunterricht gegeben.',
|
||||
amount: '1000',
|
||||
status: 'DENIED',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
const mountWrapper = () => {
|
||||
return mount(ContributionListAll, {
|
||||
global,
|
||||
})
|
||||
}
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(useQuery).mockImplementation((query) => {
|
||||
return {
|
||||
result: allContributions,
|
||||
loading,
|
||||
}
|
||||
})
|
||||
|
||||
wrapper = mountWrapper()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
describe('mount as all contributions list', () => {
|
||||
it('fetches initial data', () => {
|
||||
expect(useQuery).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
it('has a DIV .contribution-list-all', () => {
|
||||
expect(wrapper.find('div.contribution-list-all').exists()).toBe(true)
|
||||
})
|
||||
|
||||
describe('pagination', () => {
|
||||
describe('list count smaller than page size', () => {
|
||||
it('has no pagination buttons', () => {
|
||||
expect(wrapper.find('b-pagination-stub').exists()).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('list count greater than page size', () => {
|
||||
beforeEach(async () => {
|
||||
allContributions.value.listAllContributions.contributionCount = 33
|
||||
})
|
||||
|
||||
it('has pagination buttons', () => {
|
||||
expect(wrapper.find('b-pagination-stub').exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('switch page', () => {
|
||||
const scrollToMock = vi.fn()
|
||||
window.scrollTo = scrollToMock
|
||||
|
||||
beforeEach(async () => {
|
||||
allContributions.value.listAllContributions.contributionCount = 33
|
||||
await wrapper
|
||||
.findComponent({ name: 'PaginatorRouteParamsPage' })
|
||||
.vm.$emit('update:modelValue', 2)
|
||||
})
|
||||
|
||||
it('updates current page', () => {
|
||||
expect(wrapper.vm.currentPage).toBe(2)
|
||||
})
|
||||
|
||||
it.skip('scrolls to top', () => {
|
||||
expect(scrollToMock).toHaveBeenCalledWith(0, 0)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -7,7 +7,7 @@
|
||||
{{ $t('contribution.noContributions.emptyPage') }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="all-contribution-list">
|
||||
<div v-else class="contribution-list-all">
|
||||
<div v-for="item in items" :key="item.id + 'a'" class="mb-3">
|
||||
<div :id="`contributionListItem-${item.id}`">
|
||||
<contribution-list-all-item v-bind="item" />
|
||||
|
||||
@ -0,0 +1,217 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import ContributionListItem from './ContributionListItem'
|
||||
import { BRow, BCol, BCollapse, BButton, BForm, BTextArea, BFormTextarea } from 'bootstrap-vue-next'
|
||||
import VariantIcon from '@/components/VariantIcon.vue'
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
messages: {
|
||||
en: {
|
||||
short: 'Short format date',
|
||||
contribution: {
|
||||
deleted: 'Deleted contribution',
|
||||
delete: 'Delete contribution',
|
||||
confirmed: 'Confirmed contribution',
|
||||
},
|
||||
form: {
|
||||
reply: 'Reply',
|
||||
memo: 'Memo',
|
||||
},
|
||||
edit: 'Edit',
|
||||
delete: 'Delete',
|
||||
moderatorChat: 'Chat',
|
||||
},
|
||||
},
|
||||
datetimeFormats: {
|
||||
en: {
|
||||
short: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
vi.mock('@vue/apollo-composable', () => ({
|
||||
useQuery: vi.fn(),
|
||||
useLazyQuery: vi.fn(() => ({
|
||||
onResult: vi.fn(),
|
||||
onError: vi.fn(),
|
||||
load: vi.fn(),
|
||||
refetch: vi.fn(),
|
||||
})),
|
||||
useMutation: vi.fn(() => ({
|
||||
mutate: vi.fn(),
|
||||
onDone: vi.fn(),
|
||||
onError: vi.fn(),
|
||||
})),
|
||||
}))
|
||||
|
||||
vi.mock('@/composables/useToast', () => ({
|
||||
useAppToast: vi.fn(() => ({
|
||||
addToast: vi.fn(),
|
||||
toastError: vi.fn(),
|
||||
toastSuccess: vi.fn(),
|
||||
})),
|
||||
}))
|
||||
|
||||
describe('ContributionListItem', () => {
|
||||
let wrapper
|
||||
|
||||
const mocks = {
|
||||
$filters: {
|
||||
GDD: vi.fn((val) => val),
|
||||
},
|
||||
$t: vi.fn((key) => key),
|
||||
$d: (date, format) => date.toISOString(),
|
||||
}
|
||||
|
||||
const propsData = {
|
||||
contributionId: 42,
|
||||
contributionStatus: 'PENDING',
|
||||
messagesCount: 2,
|
||||
id: 1,
|
||||
createdAt: '26/07/2022',
|
||||
contributionDate: '07/06/2022',
|
||||
memo: 'Ich habe 10 Stunden die Elbwiesen von Müll befreit.',
|
||||
amount: '200',
|
||||
}
|
||||
|
||||
const mountWrapper = () => {
|
||||
return mount(ContributionListItem, {
|
||||
global: {
|
||||
plugins: [i18n],
|
||||
mocks,
|
||||
stubs: [
|
||||
'IBiPencil',
|
||||
'IBiTrash',
|
||||
'IBiChatDots',
|
||||
'BAvatar',
|
||||
'VariantIcon',
|
||||
'BButton',
|
||||
'IBiArrowDownCircle',
|
||||
'IBiArrowUpCircle',
|
||||
'IBiArrowUpShort',
|
||||
'ContributionMessagesListItem',
|
||||
],
|
||||
components: {
|
||||
BRow,
|
||||
BCol,
|
||||
BCollapse,
|
||||
BButton,
|
||||
BForm,
|
||||
BTextArea,
|
||||
BFormTextarea,
|
||||
},
|
||||
},
|
||||
props: propsData,
|
||||
})
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
wrapper = mountWrapper()
|
||||
})
|
||||
|
||||
it('has a DIV .contribution-list-item', () => {
|
||||
expect(wrapper.find('div.contribution-list-item').exists()).toBe(true)
|
||||
})
|
||||
|
||||
describe('contribution icon', () => {
|
||||
it('is bell-fill by default', () => {
|
||||
expect(wrapper.vm.icon).toBe('bell-fill')
|
||||
})
|
||||
|
||||
it('is x-circle when contributionStatus is DELETED', async () => {
|
||||
await wrapper.setProps({ contributionStatus: 'DELETED' })
|
||||
expect(wrapper.vm.icon).toBe('trash')
|
||||
})
|
||||
|
||||
it('is check when contributionStatus is CONFIRMED', async () => {
|
||||
await wrapper.setProps({ contributionStatus: 'CONFIRMED' })
|
||||
expect(wrapper.vm.icon).toBe('check')
|
||||
})
|
||||
})
|
||||
|
||||
describe('contribution variant', () => {
|
||||
it('is primary by default', () => {
|
||||
expect(wrapper.vm.variant).toBe('primary')
|
||||
})
|
||||
|
||||
it('is danger when contributionStatus is DELETED', async () => {
|
||||
await wrapper.setProps({ contributionStatus: 'DELETED' })
|
||||
expect(wrapper.vm.variant).toBe('danger')
|
||||
})
|
||||
|
||||
it('is success at when contributionStatus is CONFIRMED', async () => {
|
||||
await wrapper.setProps({ contributionStatus: 'CONFIRMED' })
|
||||
expect(wrapper.vm.variant).toBe('success')
|
||||
})
|
||||
|
||||
it('is warning at when contributionStatus is IN_PROGRESS', async () => {
|
||||
await wrapper.setProps({ contributionStatus: 'IN_PROGRESS' })
|
||||
expect(wrapper.vm.variant).toBe('205')
|
||||
})
|
||||
})
|
||||
|
||||
describe('delete contribution', () => {
|
||||
describe('edit contribution', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.find('div.test-edit-contribution').trigger('click')
|
||||
})
|
||||
|
||||
it('emits update contribution form', () => {
|
||||
expect(wrapper.emitted('update-contribution-form')).toEqual([
|
||||
[
|
||||
{
|
||||
id: 1,
|
||||
contributionDate: '07/06/2022',
|
||||
memo: 'Ich habe 10 Stunden die Elbwiesen von Müll befreit.',
|
||||
amount: '200',
|
||||
},
|
||||
],
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe('confirm deletion', () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(window, 'confirm').mockImplementation(() => true)
|
||||
wrapper.find('div.test-delete-contribution').trigger('click')
|
||||
})
|
||||
|
||||
it('emits delete contribution', () => {
|
||||
expect(wrapper.emitted('contribution-changed')).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('cancel deletion', () => {
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(window, 'confirm').mockImplementation(() => false)
|
||||
await wrapper.find('div.test-delete-contribution').trigger('click')
|
||||
})
|
||||
|
||||
it('does not emit delete contribution', () => {
|
||||
expect(wrapper.emitted('delete-contribution')).toBeFalsy()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('updateStatus', () => {
|
||||
it('updates status of a contribution', async () => {
|
||||
wrapper.vm.contributionStatus = 'IN_PROGRESS'
|
||||
|
||||
wrapper.vm.addContributionMessage({})
|
||||
|
||||
expect(wrapper.vm.localStatus).toBe('PENDING')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -62,9 +62,16 @@ vi.mock('@/components/Contributions/OpenCreationsAmount', () => ({
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@/components/Contributions/ContributionForm', () => ({
|
||||
vi.mock('@/components/Contributions/ContributionEdit', () => ({
|
||||
default: {
|
||||
name: 'ContributionForm',
|
||||
name: 'ContributionEdit',
|
||||
template: '<div></div>',
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@/components/Contributions/ContributionCreate', () => ({
|
||||
default: {
|
||||
name: 'ContributionCreate',
|
||||
template: '<div></div>',
|
||||
},
|
||||
}))
|
||||
@ -76,6 +83,13 @@ vi.mock('@/components/Contributions/ContributionList', () => ({
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@/components/Contributions/ContributionListAll', () => ({
|
||||
default: {
|
||||
name: 'ContributionListAll',
|
||||
template: '<div></div>',
|
||||
},
|
||||
}))
|
||||
|
||||
describe('Community', () => {
|
||||
let wrapper
|
||||
let mockRouter
|
||||
@ -140,9 +154,7 @@ describe('Community', () => {
|
||||
},
|
||||
components: {
|
||||
BTabs,
|
||||
},
|
||||
stub: {
|
||||
BTab: true,
|
||||
BTab,
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -156,17 +168,12 @@ describe('Community', () => {
|
||||
it('initializes with correct data', () => {
|
||||
expect(wrapper.vm.tabIndex).toBe(0)
|
||||
})
|
||||
|
||||
it('fetches initial data', () => {
|
||||
expect(mockOpenCreationsQuery).toHaveBeenCalled()
|
||||
expect(mockCountContributionsInProgress).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('tabs', () => {
|
||||
it('has three tabs', () => {
|
||||
expect(wrapper.findAll('.tabs')).toHaveLength(1)
|
||||
expect(wrapper.findAll('btab')).toHaveLength(3)
|
||||
expect(wrapper.findAllComponents(BTab)).toHaveLength(3)
|
||||
})
|
||||
|
||||
it.skip('updates tab index when route changes', async () => {
|
||||
@ -176,105 +183,20 @@ describe('Community', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('handleSaveContribution', () => {
|
||||
it('calls createContributionMutation and shows success toast on success', async () => {
|
||||
const contributionData = { date: '2023-09-12', memo: 'Test contribution', amount: '100' }
|
||||
mockCreateContributionMutation.mockResolvedValue({ data: { createContribution: true } })
|
||||
|
||||
await wrapper.vm.handleSaveContribution(contributionData)
|
||||
|
||||
expect(mockCreateContributionMutation).toHaveBeenCalledWith({
|
||||
creationDate: contributionData.date,
|
||||
memo: contributionData.memo,
|
||||
amount: contributionData.amount,
|
||||
})
|
||||
expect(mockToast.toastSuccess).toHaveBeenCalledWith('contribution.submitted')
|
||||
})
|
||||
|
||||
it('shows error toast on failure', async () => {
|
||||
const contributionData = { date: '2023-09-12', memo: 'Test contribution', amount: '100' }
|
||||
mockCreateContributionMutation.mockRejectedValue(new Error('Create Contribution failed!'))
|
||||
|
||||
await wrapper.vm.handleSaveContribution(contributionData)
|
||||
|
||||
expect(mockToast.toastError).toHaveBeenCalledWith('Create Contribution failed!')
|
||||
})
|
||||
})
|
||||
|
||||
describe('handleUpdateContribution', () => {
|
||||
it('calls updateContributionMutation and shows success toast on success', async () => {
|
||||
const contributionData = {
|
||||
id: 1,
|
||||
date: '2023-09-12',
|
||||
memo: 'Updated contribution',
|
||||
amount: '200',
|
||||
}
|
||||
mockUpdateContributionMutation.mockResolvedValue({ data: { updateContribution: true } })
|
||||
|
||||
await wrapper.vm.handleUpdateContribution(contributionData)
|
||||
|
||||
expect(mockUpdateContributionMutation).toHaveBeenCalledWith({
|
||||
contributionId: contributionData.id,
|
||||
creationDate: contributionData.date,
|
||||
memo: contributionData.memo,
|
||||
amount: contributionData.amount,
|
||||
})
|
||||
expect(mockToast.toastSuccess).toHaveBeenCalledWith('contribution.updated')
|
||||
})
|
||||
|
||||
it('shows error toast on failure', async () => {
|
||||
const contributionData = {
|
||||
id: 1,
|
||||
date: '2023-09-12',
|
||||
memo: 'Updated contribution',
|
||||
amount: '200',
|
||||
}
|
||||
mockUpdateContributionMutation.mockRejectedValue(new Error('Update Contribution failed!'))
|
||||
|
||||
await wrapper.vm.handleUpdateContribution(contributionData)
|
||||
|
||||
expect(mockToast.toastError).toHaveBeenCalledWith('Update Contribution failed!')
|
||||
})
|
||||
})
|
||||
|
||||
describe('handleDeleteContribution', () => {
|
||||
it('calls deleteContributionMutation and shows success toast on success', async () => {
|
||||
const contributionData = { id: 1 }
|
||||
mockDeleteContributionMutation.mockResolvedValue({ data: { deleteContribution: true } })
|
||||
|
||||
await wrapper.vm.handleDeleteContribution(contributionData)
|
||||
|
||||
expect(mockDeleteContributionMutation).toHaveBeenCalledWith({ id: contributionData.id })
|
||||
expect(mockToast.toastSuccess).toHaveBeenCalledWith('contribution.deleted')
|
||||
})
|
||||
|
||||
it('shows error toast on failure', async () => {
|
||||
const contributionData = { id: 1 }
|
||||
mockDeleteContributionMutation.mockRejectedValue(new Error('Delete Contribution failed!'))
|
||||
|
||||
await wrapper.vm.handleDeleteContribution(contributionData)
|
||||
|
||||
expect(mockToast.toastError).toHaveBeenCalledWith('Delete Contribution failed!')
|
||||
})
|
||||
})
|
||||
|
||||
describe('handleUpdateContributionForm', () => {
|
||||
it('updates form data and changes tab', () => {
|
||||
const contributionData = {
|
||||
id: 2,
|
||||
contributionDate: '2023-09-12',
|
||||
memo: 'Test contribution',
|
||||
amount: '300',
|
||||
item: { id: 2, contributionDate: '2023-09-12', memo: 'Test contribution', amount: '300' },
|
||||
page: 2,
|
||||
}
|
||||
|
||||
wrapper.vm.handleUpdateContributionForm(contributionData)
|
||||
|
||||
expect(wrapper.vm.form).toEqual({
|
||||
expect(wrapper.vm.itemData).toEqual({
|
||||
id: 2,
|
||||
date: '2023-09-12',
|
||||
contributionDate: '2023-09-12',
|
||||
memo: 'Test contribution',
|
||||
amount: '300',
|
||||
hours: 15, // 300 / 20
|
||||
})
|
||||
expect(wrapper.vm.tabIndex).toBe(0)
|
||||
expect(mockRouter.push).toHaveBeenCalledWith({ params: { tab: 'contribute' } })
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user