mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into 2632-feature-dockerfile-for-federation
This commit is contained in:
commit
c2a5482d6a
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -497,7 +497,7 @@ jobs:
|
|||||||
report_name: Coverage Admin Interface
|
report_name: Coverage Admin Interface
|
||||||
type: lcov
|
type: lcov
|
||||||
result_path: ./coverage/lcov.info
|
result_path: ./coverage/lcov.info
|
||||||
min_coverage: 96
|
min_coverage: 97
|
||||||
token: ${{ github.token }}
|
token: ${{ github.token }}
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|||||||
@ -42,29 +42,72 @@ describe('ContributionLink', () => {
|
|||||||
expect(wrapper.find('div.contribution-link').exists()).toBe(true)
|
expect(wrapper.find('div.contribution-link').exists()).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('function editContributionLinkData', () => {
|
it('has one contribution link in table', () => {
|
||||||
beforeEach(() => {
|
expect(wrapper.find('div.contribution-link-list').find('tbody').findAll('tr')).toHaveLength(1)
|
||||||
wrapper.vm.editContributionLinkData()
|
})
|
||||||
|
|
||||||
|
it('has contribution form not visible by default', () => {
|
||||||
|
expect(wrapper.find('#newContribution').isVisible()).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('click on create new contribution', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await wrapper.find('[data-test="new-contribution-link-button"]').trigger('click')
|
||||||
})
|
})
|
||||||
it('emits toggle::collapse new Contribution', async () => {
|
|
||||||
await expect(wrapper.vm.$root.$emit('bv::toggle::collapse', 'newContribution')).toBeTruthy()
|
it('shows the contribution form', () => {
|
||||||
|
expect(wrapper.find('#newContribution').isVisible()).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('click on create new contribution again', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await wrapper.find('[data-test="new-contribution-link-button"]').trigger('click')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('closes the contribution form', () => {
|
||||||
|
expect(wrapper.find('#newContribution').isVisible()).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('click on close button', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await wrapper.find('button.btn-secondary').trigger('click')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('closes the contribution form', () => {
|
||||||
|
expect(wrapper.find('#newContribution').isVisible()).toBe(false)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('function closeContributionForm', () => {
|
describe('edit contribution link', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await wrapper.setData({ visible: true })
|
await wrapper
|
||||||
wrapper.vm.closeContributionForm()
|
.find('div.contribution-link-list')
|
||||||
|
.find('tbody')
|
||||||
|
.findAll('tr')
|
||||||
|
.at(0)
|
||||||
|
.findAll('button')
|
||||||
|
.at(1)
|
||||||
|
.trigger('click')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('emits toggle::collapse close Contribution-Form ', async () => {
|
it('shows the contribution form', () => {
|
||||||
await expect(wrapper.vm.$root.$emit('bv::toggle::collapse', 'newContribution')).toBeTruthy()
|
expect(wrapper.find('#newContribution').isVisible()).toBe(true)
|
||||||
})
|
})
|
||||||
it('editContributionLink is false', async () => {
|
|
||||||
await expect(wrapper.vm.editContributionLink).toBe(false)
|
it('does not show the new contribution button', () => {
|
||||||
|
expect(wrapper.find('[data-test="new-contribution-link-button"]').exists()).toBe(false)
|
||||||
})
|
})
|
||||||
it('contributionLinkData is empty', async () => {
|
|
||||||
await expect(wrapper.vm.contributionLinkData).toEqual({})
|
describe('click on close button', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await wrapper.find('button.btn-secondary').trigger('click')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('closes the contribution form', () => {
|
||||||
|
expect(wrapper.find('#newContribution').isVisible()).toBe(false)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -10,8 +10,9 @@
|
|||||||
>
|
>
|
||||||
<b-button
|
<b-button
|
||||||
v-if="!editContributionLink"
|
v-if="!editContributionLink"
|
||||||
v-b-toggle.newContribution
|
@click="visible = !visible"
|
||||||
class="my-3 d-flex justify-content-left"
|
class="my-3 d-flex justify-content-left"
|
||||||
|
data-test="new-contribution-link-button"
|
||||||
>
|
>
|
||||||
{{ $t('math.plus') }} {{ $t('contributionLink.newContributionLink') }}
|
{{ $t('math.plus') }} {{ $t('contributionLink.newContributionLink') }}
|
||||||
</b-button>
|
</b-button>
|
||||||
|
|||||||
@ -70,8 +70,6 @@ export default {
|
|||||||
formatter: (value, key, item) => {
|
formatter: (value, key, item) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
return this.$d(new Date(value))
|
return this.$d(new Date(value))
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -81,8 +79,6 @@ export default {
|
|||||||
formatter: (value, key, item) => {
|
formatter: (value, key, item) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
return this.$d(new Date(value))
|
return this.$d(new Date(value))
|
||||||
} else {
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -68,13 +68,23 @@ describe('NavBar', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('wallet', () => {
|
describe('wallet', () => {
|
||||||
const assignLocationSpy = jest.fn()
|
const windowLocationMock = jest.fn()
|
||||||
|
const windowLocation = window.location
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
delete window.location
|
||||||
|
window.location = {
|
||||||
|
assign: windowLocationMock,
|
||||||
|
}
|
||||||
await wrapper.findAll('.nav-item').at(5).find('a').trigger('click')
|
await wrapper.findAll('.nav-item').at(5).find('a').trigger('click')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
delete window.location
|
||||||
|
window.location = windowLocation
|
||||||
|
})
|
||||||
|
|
||||||
it.skip('changes window location to wallet', () => {
|
it.skip('changes window location to wallet', () => {
|
||||||
expect(assignLocationSpy).toBeCalledWith('valid-token')
|
expect(windowLocationMock()).toBe('valid-token')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('dispatches logout to store', () => {
|
it('dispatches logout to store', () => {
|
||||||
@ -84,6 +94,7 @@ describe('NavBar', () => {
|
|||||||
|
|
||||||
describe('logout', () => {
|
describe('logout', () => {
|
||||||
const windowLocationMock = jest.fn()
|
const windowLocationMock = jest.fn()
|
||||||
|
const windowLocation = window.location
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
delete window.location
|
delete window.location
|
||||||
window.location = {
|
window.location = {
|
||||||
@ -92,6 +103,11 @@ describe('NavBar', () => {
|
|||||||
await wrapper.findAll('.nav-item').at(5).find('a').trigger('click')
|
await wrapper.findAll('.nav-item').at(5).find('a').trigger('click')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
delete window.location
|
||||||
|
window.location = windowLocation
|
||||||
|
})
|
||||||
|
|
||||||
it('redirects to /logout', () => {
|
it('redirects to /logout', () => {
|
||||||
expect(windowLocationMock).toBeCalledWith('http://localhost/login')
|
expect(windowLocationMock).toBeCalledWith('http://localhost/login')
|
||||||
})
|
})
|
||||||
|
|||||||
@ -10,12 +10,11 @@
|
|||||||
<b-collapse id="nav-collapse" is-nav>
|
<b-collapse id="nav-collapse" is-nav>
|
||||||
<b-navbar-nav>
|
<b-navbar-nav>
|
||||||
<b-nav-item to="/user">{{ $t('navbar.user_search') }}</b-nav-item>
|
<b-nav-item to="/user">{{ $t('navbar.user_search') }}</b-nav-item>
|
||||||
<b-nav-item
|
<b-nav-item class="bg-color-creation p-1" to="/creation-confirm">
|
||||||
v-show="$store.state.openCreations > 0"
|
{{ $t('creation') }}
|
||||||
class="bg-color-creation p-1"
|
<b-badge v-show="$store.state.openCreations > 0" variant="danger">
|
||||||
to="/creation-confirm"
|
{{ $store.state.openCreations }}
|
||||||
>
|
</b-badge>
|
||||||
{{ $store.state.openCreations }} {{ $t('navbar.open_creation') }}
|
|
||||||
</b-nav-item>
|
</b-nav-item>
|
||||||
<b-nav-item to="/contribution-links">
|
<b-nav-item to="/contribution-links">
|
||||||
{{ $t('navbar.automaticContributions') }}
|
{{ $t('navbar.automaticContributions') }}
|
||||||
@ -55,7 +54,4 @@ export default {
|
|||||||
height: 2rem;
|
height: 2rem;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
.bg-color-creation {
|
|
||||||
background-color: #cf1010dc;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -13,7 +13,8 @@
|
|||||||
<b-row>
|
<b-row>
|
||||||
<b-col class="col-3">{{ $t('creation_for_month') }}</b-col>
|
<b-col class="col-3">{{ $t('creation_for_month') }}</b-col>
|
||||||
<b-col class="h3">
|
<b-col class="h3">
|
||||||
{{ $d(new Date(item.date), 'month') }} {{ $d(new Date(item.date), 'year') }}
|
{{ $d(new Date(item.contributionDate), 'month') }}
|
||||||
|
{{ $d(new Date(item.contributionDate), 'year') }}
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row>
|
<b-row>
|
||||||
|
|||||||
@ -1,6 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="open-creations-table">
|
<div class="open-creations-table">
|
||||||
<b-table-lite :items="items" :fields="fields" caption-top striped hover stacked="md">
|
<b-table-lite
|
||||||
|
:items="items"
|
||||||
|
:fields="fields"
|
||||||
|
caption-top
|
||||||
|
striped
|
||||||
|
hover
|
||||||
|
stacked="md"
|
||||||
|
:tbody-tr-class="rowClass"
|
||||||
|
>
|
||||||
|
<template #cell(state)="row">
|
||||||
|
<b-icon :icon="getStatusIcon(row.item.state)"></b-icon>
|
||||||
|
</template>
|
||||||
<template #cell(bookmark)="row">
|
<template #cell(bookmark)="row">
|
||||||
<b-button
|
<b-button
|
||||||
variant="danger"
|
variant="danger"
|
||||||
@ -37,6 +48,16 @@
|
|||||||
</b-button>
|
</b-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template #cell(reActive)>
|
||||||
|
<b-button variant="warning" size="md" class="mr-2">
|
||||||
|
<b-icon icon="arrow-up" variant="light"></b-icon>
|
||||||
|
</b-button>
|
||||||
|
</template>
|
||||||
|
<template #cell(chatCreation)="row">
|
||||||
|
<b-button v-if="row.item.messagesCount > 0" @click="rowToggleDetails(row, 0)">
|
||||||
|
<b-icon icon="chat-dots"></b-icon>
|
||||||
|
</b-button>
|
||||||
|
</template>
|
||||||
<template #cell(deny)="row">
|
<template #cell(deny)="row">
|
||||||
<div v-if="$store.state.moderator.id !== row.item.userId">
|
<div v-if="$store.state.moderator.id !== row.item.userId">
|
||||||
<b-button
|
<b-button
|
||||||
@ -100,6 +121,14 @@ import RowDetails from '../RowDetails.vue'
|
|||||||
import EditCreationFormular from '../EditCreationFormular.vue'
|
import EditCreationFormular from '../EditCreationFormular.vue'
|
||||||
import ContributionMessagesList from '../ContributionMessages/ContributionMessagesList.vue'
|
import ContributionMessagesList from '../ContributionMessages/ContributionMessagesList.vue'
|
||||||
|
|
||||||
|
const iconMap = {
|
||||||
|
IN_PROGRESS: 'question-square',
|
||||||
|
PENDING: 'bell-fill',
|
||||||
|
CONFIRMED: 'check',
|
||||||
|
DELETED: 'trash',
|
||||||
|
DENIED: 'x-circle',
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'OpenCreationsTable',
|
name: 'OpenCreationsTable',
|
||||||
mixins: [toggleRowDetails],
|
mixins: [toggleRowDetails],
|
||||||
@ -129,6 +158,14 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getStatusIcon(status) {
|
||||||
|
return iconMap[status] ? iconMap[status] : 'default-icon'
|
||||||
|
},
|
||||||
|
rowClass(item, type) {
|
||||||
|
if (!item || type !== 'row') return
|
||||||
|
if (item.state === 'CONFIRMED') return 'table-success'
|
||||||
|
if (item.state === 'DENIED') return 'table-info'
|
||||||
|
},
|
||||||
updateCreationData(data) {
|
updateCreationData(data) {
|
||||||
const row = data.row
|
const row = data.row
|
||||||
this.$emit('update-contributions', data)
|
this.$emit('update-contributions', data)
|
||||||
|
|||||||
34
admin/src/graphql/listAllContributions.js
Normal file
34
admin/src/graphql/listAllContributions.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
export const listAllContributions = gql`
|
||||||
|
query (
|
||||||
|
$currentPage: Int = 1
|
||||||
|
$pageSize: Int = 25
|
||||||
|
$order: Order = DESC
|
||||||
|
$statusFilter: [ContributionStatus!]
|
||||||
|
) {
|
||||||
|
listAllContributions(
|
||||||
|
currentPage: $currentPage
|
||||||
|
pageSize: $pageSize
|
||||||
|
order: $order
|
||||||
|
statusFilter: $statusFilter
|
||||||
|
) {
|
||||||
|
contributionCount
|
||||||
|
contributionList {
|
||||||
|
id
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
amount
|
||||||
|
memo
|
||||||
|
createdAt
|
||||||
|
contributionDate
|
||||||
|
confirmedAt
|
||||||
|
confirmedBy
|
||||||
|
state
|
||||||
|
messagesCount
|
||||||
|
deniedAt
|
||||||
|
deniedBy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
@ -1,20 +0,0 @@
|
|||||||
import gql from 'graphql-tag'
|
|
||||||
|
|
||||||
export const listUnconfirmedContributions = gql`
|
|
||||||
query {
|
|
||||||
listUnconfirmedContributions {
|
|
||||||
id
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
userId
|
|
||||||
email
|
|
||||||
amount
|
|
||||||
memo
|
|
||||||
date
|
|
||||||
moderator
|
|
||||||
creation
|
|
||||||
state
|
|
||||||
messageCount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"all_emails": "Alle Nutzer",
|
"all_emails": "Alle Nutzer",
|
||||||
"back": "zurück",
|
"back": "zurück",
|
||||||
|
"chat": "Chat",
|
||||||
"contributionLink": {
|
"contributionLink": {
|
||||||
"amount": "Betrag",
|
"amount": "Betrag",
|
||||||
"changeSaved": "Änderungen gespeichert",
|
"changeSaved": "Änderungen gespeichert",
|
||||||
@ -29,6 +30,15 @@
|
|||||||
"validFrom": "Startdatum",
|
"validFrom": "Startdatum",
|
||||||
"validTo": "Enddatum"
|
"validTo": "Enddatum"
|
||||||
},
|
},
|
||||||
|
"contributions": {
|
||||||
|
"all": "Alle",
|
||||||
|
"confirms": "Bestätigt",
|
||||||
|
"deleted": "Gelöscht",
|
||||||
|
"denied": "Abgelehnt",
|
||||||
|
"open": "Offen"
|
||||||
|
},
|
||||||
|
"created": "Geschöpft",
|
||||||
|
"createdAt": "Angelegt",
|
||||||
"creation": "Schöpfung",
|
"creation": "Schöpfung",
|
||||||
"creationList": "Schöpfungsliste",
|
"creationList": "Schöpfungsliste",
|
||||||
"creation_form": {
|
"creation_form": {
|
||||||
@ -48,7 +58,6 @@
|
|||||||
"update_creation": "Schöpfung aktualisieren"
|
"update_creation": "Schöpfung aktualisieren"
|
||||||
},
|
},
|
||||||
"creation_for_month": "Schöpfung für Monat",
|
"creation_for_month": "Schöpfung für Monat",
|
||||||
"date": "Datum",
|
|
||||||
"delete": "Löschen",
|
"delete": "Löschen",
|
||||||
"deleted": "gelöscht",
|
"deleted": "gelöscht",
|
||||||
"deleted_user": "Alle gelöschten Nutzer",
|
"deleted_user": "Alle gelöschten Nutzer",
|
||||||
@ -92,13 +101,13 @@
|
|||||||
"message": {
|
"message": {
|
||||||
"request": "Die Anfrage wurde gesendet."
|
"request": "Die Anfrage wurde gesendet."
|
||||||
},
|
},
|
||||||
|
"mod": "Mod",
|
||||||
"moderator": "Moderator",
|
"moderator": "Moderator",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"automaticContributions": "Automatische Beiträge",
|
"automaticContributions": "Automatische Beiträge",
|
||||||
"logout": "Abmelden",
|
"logout": "Abmelden",
|
||||||
"my-account": "Mein Konto",
|
"my-account": "Mein Konto",
|
||||||
"open_creation": "Offene Schöpfungen",
|
|
||||||
"statistic": "Statistik",
|
"statistic": "Statistik",
|
||||||
"user_search": "Nutzersuche"
|
"user_search": "Nutzersuche"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"all_emails": "All users",
|
"all_emails": "All users",
|
||||||
"back": "back",
|
"back": "back",
|
||||||
|
"chat": "Chat",
|
||||||
"contributionLink": {
|
"contributionLink": {
|
||||||
"amount": "Amount",
|
"amount": "Amount",
|
||||||
"changeSaved": "Changes saved",
|
"changeSaved": "Changes saved",
|
||||||
@ -29,6 +30,15 @@
|
|||||||
"validFrom": "Start-date",
|
"validFrom": "Start-date",
|
||||||
"validTo": "End-Date"
|
"validTo": "End-Date"
|
||||||
},
|
},
|
||||||
|
"contributions": {
|
||||||
|
"all": "All",
|
||||||
|
"confirms": "Confirmed",
|
||||||
|
"deleted": "Deleted",
|
||||||
|
"denied": "Denied",
|
||||||
|
"open": "Open"
|
||||||
|
},
|
||||||
|
"created": "Confirmed",
|
||||||
|
"createdAt": "Created",
|
||||||
"creation": "Creation",
|
"creation": "Creation",
|
||||||
"creationList": "Creation list",
|
"creationList": "Creation list",
|
||||||
"creation_form": {
|
"creation_form": {
|
||||||
@ -48,7 +58,6 @@
|
|||||||
"update_creation": "Creation update"
|
"update_creation": "Creation update"
|
||||||
},
|
},
|
||||||
"creation_for_month": "Creation for month",
|
"creation_for_month": "Creation for month",
|
||||||
"date": "Date",
|
|
||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"deleted": "deleted",
|
"deleted": "deleted",
|
||||||
"deleted_user": "All deleted user",
|
"deleted_user": "All deleted user",
|
||||||
@ -92,13 +101,13 @@
|
|||||||
"message": {
|
"message": {
|
||||||
"request": "Request has been sent."
|
"request": "Request has been sent."
|
||||||
},
|
},
|
||||||
|
"mod": "Mod",
|
||||||
"moderator": "Moderator",
|
"moderator": "Moderator",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"automaticContributions": "Automatic Contributions",
|
"automaticContributions": "Automatic Contributions",
|
||||||
"logout": "Logout",
|
"logout": "Logout",
|
||||||
"my-account": "My Account",
|
"my-account": "My Account",
|
||||||
"open_creation": "Open creations",
|
|
||||||
"statistic": "Statistic",
|
"statistic": "Statistic",
|
||||||
"user_search": "User search"
|
"user_search": "User search"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { toastErrorSpy } from '../../test/testSetup'
|
|||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
const apolloQueryMock = jest.fn().mockResolvedValueOnce({
|
const apolloQueryMock = jest.fn().mockResolvedValue({
|
||||||
data: {
|
data: {
|
||||||
listContributionLinks: {
|
listContributionLinks: {
|
||||||
links: [
|
links: [
|
||||||
@ -47,6 +47,7 @@ describe('ContributionLinks', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = Wrapper()
|
wrapper = Wrapper()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('apollo returns', () => {
|
describe('apollo returns', () => {
|
||||||
it('calls listContributionLinks', () => {
|
it('calls listContributionLinks', () => {
|
||||||
expect(apolloQueryMock).toBeCalledWith(
|
expect(apolloQueryMock).toBeCalledWith(
|
||||||
@ -57,7 +58,7 @@ describe('ContributionLinks', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe.skip('query transaction with error', () => {
|
describe('query transaction with error', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
apolloQueryMock.mockRejectedValue({ message: 'OUCH!' })
|
apolloQueryMock.mockRejectedValue({ message: 'OUCH!' })
|
||||||
wrapper = Wrapper()
|
wrapper = Wrapper()
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils'
|
|||||||
import CreationConfirm from './CreationConfirm.vue'
|
import CreationConfirm from './CreationConfirm.vue'
|
||||||
import { adminDeleteContribution } from '../graphql/adminDeleteContribution'
|
import { adminDeleteContribution } from '../graphql/adminDeleteContribution'
|
||||||
import { denyContribution } from '../graphql/denyContribution'
|
import { denyContribution } from '../graphql/denyContribution'
|
||||||
import { listUnconfirmedContributions } from '../graphql/listUnconfirmedContributions'
|
import { listAllContributions } from '../graphql/listAllContributions'
|
||||||
import { confirmContribution } from '../graphql/confirmContribution'
|
import { confirmContribution } from '../graphql/confirmContribution'
|
||||||
import { toastErrorSpy, toastSuccessSpy } from '../../test/testSetup'
|
import { toastErrorSpy, toastSuccessSpy } from '../../test/testSetup'
|
||||||
import VueApollo from 'vue-apollo'
|
import VueApollo from 'vue-apollo'
|
||||||
@ -38,50 +38,68 @@ const mocks = {
|
|||||||
|
|
||||||
const defaultData = () => {
|
const defaultData = () => {
|
||||||
return {
|
return {
|
||||||
listUnconfirmedContributions: [
|
listAllContributions: {
|
||||||
{
|
contributionCount: 2,
|
||||||
id: 1,
|
contributionList: [
|
||||||
firstName: 'Bibi',
|
{
|
||||||
lastName: 'Bloxberg',
|
id: 1,
|
||||||
userId: 99,
|
firstName: 'Bibi',
|
||||||
email: 'bibi@bloxberg.de',
|
lastName: 'Bloxberg',
|
||||||
amount: 500,
|
userId: 99,
|
||||||
memo: 'Danke für alles',
|
email: 'bibi@bloxberg.de',
|
||||||
date: new Date(),
|
amount: 500,
|
||||||
moderator: 1,
|
memo: 'Danke für alles',
|
||||||
state: 'PENDING',
|
date: new Date(),
|
||||||
creation: [500, 500, 500],
|
moderator: 1,
|
||||||
messageCount: 0,
|
state: 'PENDING',
|
||||||
},
|
creation: [500, 500, 500],
|
||||||
{
|
messagesCount: 0,
|
||||||
id: 2,
|
deniedBy: null,
|
||||||
firstName: 'Räuber',
|
deniedAt: null,
|
||||||
lastName: 'Hotzenplotz',
|
confirmedBy: null,
|
||||||
userId: 100,
|
confirmedAt: null,
|
||||||
email: 'raeuber@hotzenplotz.de',
|
contributionDate: new Date(),
|
||||||
amount: 1000000,
|
deletedBy: null,
|
||||||
memo: 'Gut Ergattert',
|
deletedAt: null,
|
||||||
date: new Date(),
|
createdAt: new Date(),
|
||||||
moderator: 1,
|
},
|
||||||
state: 'PENDING',
|
{
|
||||||
creation: [500, 500, 500],
|
id: 2,
|
||||||
messageCount: 0,
|
firstName: 'Räuber',
|
||||||
},
|
lastName: 'Hotzenplotz',
|
||||||
],
|
userId: 100,
|
||||||
|
email: 'raeuber@hotzenplotz.de',
|
||||||
|
amount: 1000000,
|
||||||
|
memo: 'Gut Ergattert',
|
||||||
|
date: new Date(),
|
||||||
|
moderator: 1,
|
||||||
|
state: 'PENDING',
|
||||||
|
creation: [500, 500, 500],
|
||||||
|
messagesCount: 0,
|
||||||
|
deniedBy: null,
|
||||||
|
deniedAt: null,
|
||||||
|
confirmedBy: null,
|
||||||
|
confirmedAt: null,
|
||||||
|
contributionDate: new Date(),
|
||||||
|
deletedBy: null,
|
||||||
|
deletedAt: null,
|
||||||
|
createdAt: new Date(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('CreationConfirm', () => {
|
describe('CreationConfirm', () => {
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|
||||||
const listUnconfirmedContributionsMock = jest.fn()
|
|
||||||
const adminDeleteContributionMock = jest.fn()
|
const adminDeleteContributionMock = jest.fn()
|
||||||
const adminDenyContributionMock = jest.fn()
|
const adminDenyContributionMock = jest.fn()
|
||||||
const confirmContributionMock = jest.fn()
|
const confirmContributionMock = jest.fn()
|
||||||
|
|
||||||
mockClient.setRequestHandler(
|
mockClient.setRequestHandler(
|
||||||
listUnconfirmedContributions,
|
listAllContributions,
|
||||||
listUnconfirmedContributionsMock
|
jest
|
||||||
|
.fn()
|
||||||
.mockRejectedValueOnce({ message: 'Ouch!' })
|
.mockRejectedValueOnce({ message: 'Ouch!' })
|
||||||
.mockResolvedValue({ data: defaultData() }),
|
.mockResolvedValue({ data: defaultData() }),
|
||||||
)
|
)
|
||||||
@ -117,6 +135,10 @@ describe('CreationConfirm', () => {
|
|||||||
it('toast an error message', () => {
|
it('toast an error message', () => {
|
||||||
expect(toastErrorSpy).toBeCalledWith('Ouch!')
|
expect(toastErrorSpy).toBeCalledWith('Ouch!')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('has statusFilter ["IN_PROGRESS", "PENDING"]', () => {
|
||||||
|
expect(wrapper.vm.statusFilter).toEqual(['IN_PROGRESS', 'PENDING'])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('server response is succes', () => {
|
describe('server response is succes', () => {
|
||||||
@ -125,17 +147,7 @@ describe('CreationConfirm', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('has two pending creations', () => {
|
it('has two pending creations', () => {
|
||||||
expect(wrapper.vm.pendingCreations).toHaveLength(2)
|
expect(wrapper.find('tbody').findAll('tr')).toHaveLength(2)
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('store', () => {
|
|
||||||
it('commits resetOpenCreations to store', () => {
|
|
||||||
expect(storeCommitMock).toBeCalledWith('resetOpenCreations')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('commits setOpenCreations to store', () => {
|
|
||||||
expect(storeCommitMock).toBeCalledWith('setOpenCreations', 2)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -316,5 +328,94 @@ describe('CreationConfirm', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('filter tabs', () => {
|
||||||
|
describe('click tab "confirmed"', () => {
|
||||||
|
let refetchSpy
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
refetchSpy = jest.spyOn(wrapper.vm.$apollo.queries.ListAllContributions, 'refetch')
|
||||||
|
await wrapper.find('a[data-test="confirmed"]').trigger('click')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('has statusFilter set to ["CONFIRMED"]', () => {
|
||||||
|
expect(
|
||||||
|
wrapper.vm.$apollo.queries.ListAllContributions.observer.options.variables,
|
||||||
|
).toMatchObject({ statusFilter: ['CONFIRMED'] })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refetches contributions', () => {
|
||||||
|
expect(refetchSpy).toBeCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('click tab "open"', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
refetchSpy = jest.spyOn(wrapper.vm.$apollo.queries.ListAllContributions, 'refetch')
|
||||||
|
await wrapper.find('a[data-test="open"]').trigger('click')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('has statusFilter set to ["IN_PROGRESS", "PENDING"]', () => {
|
||||||
|
expect(
|
||||||
|
wrapper.vm.$apollo.queries.ListAllContributions.observer.options.variables,
|
||||||
|
).toMatchObject({ statusFilter: ['IN_PROGRESS', 'PENDING'] })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refetches contributions', () => {
|
||||||
|
expect(refetchSpy).toBeCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('click tab "denied"', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
refetchSpy = jest.spyOn(wrapper.vm.$apollo.queries.ListAllContributions, 'refetch')
|
||||||
|
await wrapper.find('a[data-test="denied"]').trigger('click')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('has statusFilter set to ["DENIED"]', () => {
|
||||||
|
expect(
|
||||||
|
wrapper.vm.$apollo.queries.ListAllContributions.observer.options.variables,
|
||||||
|
).toMatchObject({ statusFilter: ['DENIED'] })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refetches contributions', () => {
|
||||||
|
expect(refetchSpy).toBeCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('click tab "all"', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
refetchSpy = jest.spyOn(wrapper.vm.$apollo.queries.ListAllContributions, 'refetch')
|
||||||
|
await wrapper.find('a[data-test="all"]').trigger('click')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('has statusFilter set to ["IN_PROGRESS", "PENDING", "CONFIRMED", "DENIED", "DELETED"]', () => {
|
||||||
|
expect(
|
||||||
|
wrapper.vm.$apollo.queries.ListAllContributions.observer.options.variables,
|
||||||
|
).toMatchObject({
|
||||||
|
statusFilter: ['IN_PROGRESS', 'PENDING', 'CONFIRMED', 'DENIED', 'DELETED'],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('refetches contributions', () => {
|
||||||
|
expect(refetchSpy).toBeCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('update status', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await wrapper.findComponent({ name: 'OpenCreationsTable' }).vm.$emit('update-state', 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
it.skip('updates the status', () => {
|
||||||
|
expect(wrapper.vm.items.find((obj) => obj.id === 2).messagesCount).toBe(1)
|
||||||
|
expect(wrapper.vm.items.find((obj) => obj.id === 2).state).toBe('IN_PROGRESS')
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,6 +1,50 @@
|
|||||||
<!-- eslint-disable @intlify/vue-i18n/no-dynamic-keys -->
|
<!-- eslint-disable @intlify/vue-i18n/no-dynamic-keys -->
|
||||||
<template>
|
<template>
|
||||||
<div class="creation-confirm">
|
<div class="creation-confirm">
|
||||||
|
<div>
|
||||||
|
<b-tabs v-model="tabIndex" content-class="mt-3" fill>
|
||||||
|
<b-tab active :title-link-attributes="{ 'data-test': 'open' }">
|
||||||
|
<template #title>
|
||||||
|
{{ $t('contributions.open') }}
|
||||||
|
<b-badge v-if="$store.state.openCreations > 0" variant="danger">
|
||||||
|
{{ $store.state.openCreations }}
|
||||||
|
</b-badge>
|
||||||
|
</template>
|
||||||
|
</b-tab>
|
||||||
|
<b-tab
|
||||||
|
:title="$t('contributions.confirms')"
|
||||||
|
:title-link-attributes="{ 'data-test': 'confirmed' }"
|
||||||
|
/>
|
||||||
|
<b-tab
|
||||||
|
:title="$t('contributions.denied')"
|
||||||
|
:title-link-attributes="{ 'data-test': 'denied' }"
|
||||||
|
/>
|
||||||
|
<b-tab
|
||||||
|
:title="$t('contributions.deleted')"
|
||||||
|
:title-link-attributes="{ 'data-test': 'deleted' }"
|
||||||
|
/>
|
||||||
|
<b-tab :title="$t('contributions.all')" :title-link-attributes="{ 'data-test': 'all' }" />
|
||||||
|
</b-tabs>
|
||||||
|
</div>
|
||||||
|
<open-creations-table
|
||||||
|
class="mt-4"
|
||||||
|
:items="items"
|
||||||
|
:fields="fields"
|
||||||
|
@show-overlay="showOverlay"
|
||||||
|
@update-state="updateStatus"
|
||||||
|
@update-contributions="$apollo.queries.AllContributions.refetch()"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<b-pagination
|
||||||
|
pills
|
||||||
|
size="lg"
|
||||||
|
v-model="currentPage"
|
||||||
|
:per-page="pageSize"
|
||||||
|
:total-rows="rows"
|
||||||
|
align="center"
|
||||||
|
:hide-ellipsis="true"
|
||||||
|
></b-pagination>
|
||||||
|
|
||||||
<div v-if="overlay" id="overlay" @dblclick="overlay = false">
|
<div v-if="overlay" id="overlay" @dblclick="overlay = false">
|
||||||
<overlay :item="item" @overlay-cancel="overlay = false">
|
<overlay :item="item" @overlay-cancel="overlay = false">
|
||||||
<template #title>
|
<template #title>
|
||||||
@ -24,24 +68,24 @@
|
|||||||
</template>
|
</template>
|
||||||
</overlay>
|
</overlay>
|
||||||
</div>
|
</div>
|
||||||
<open-creations-table
|
|
||||||
class="mt-4"
|
|
||||||
:items="pendingCreations"
|
|
||||||
:fields="fields"
|
|
||||||
@show-overlay="showOverlay"
|
|
||||||
@update-state="updateState"
|
|
||||||
@update-contributions="$apollo.queries.PendingContributions.refetch()"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Overlay from '../components/Overlay.vue'
|
import Overlay from '../components/Overlay.vue'
|
||||||
import OpenCreationsTable from '../components/Tables/OpenCreationsTable.vue'
|
import OpenCreationsTable from '../components/Tables/OpenCreationsTable.vue'
|
||||||
import { listUnconfirmedContributions } from '../graphql/listUnconfirmedContributions'
|
import { listAllContributions } from '../graphql/listAllContributions'
|
||||||
import { adminDeleteContribution } from '../graphql/adminDeleteContribution'
|
import { adminDeleteContribution } from '../graphql/adminDeleteContribution'
|
||||||
import { confirmContribution } from '../graphql/confirmContribution'
|
import { confirmContribution } from '../graphql/confirmContribution'
|
||||||
import { denyContribution } from '../graphql/denyContribution'
|
import { denyContribution } from '../graphql/denyContribution'
|
||||||
|
|
||||||
|
const FILTER_TAB_MAP = [
|
||||||
|
['IN_PROGRESS', 'PENDING'],
|
||||||
|
['CONFIRMED'],
|
||||||
|
['DENIED'],
|
||||||
|
['DELETED'],
|
||||||
|
['IN_PROGRESS', 'PENDING', 'CONFIRMED', 'DENIED', 'DELETED'],
|
||||||
|
]
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CreationConfirm',
|
name: 'CreationConfirm',
|
||||||
components: {
|
components: {
|
||||||
@ -50,10 +94,14 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pendingCreations: [],
|
tabIndex: 0,
|
||||||
|
items: [],
|
||||||
overlay: false,
|
overlay: false,
|
||||||
item: {},
|
item: {},
|
||||||
variant: 'confirm',
|
variant: 'confirm',
|
||||||
|
rows: 0,
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 25,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -112,7 +160,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
updatePendingCreations(id) {
|
updatePendingCreations(id) {
|
||||||
this.pendingCreations = this.pendingCreations.filter((obj) => obj.id !== id)
|
this.items = this.items.filter((obj) => obj.id !== id)
|
||||||
this.$store.commit('openCreationsMinus', 1)
|
this.$store.commit('openCreationsMinus', 1)
|
||||||
},
|
},
|
||||||
showOverlay(item, variant) {
|
showOverlay(item, variant) {
|
||||||
@ -120,38 +168,155 @@ export default {
|
|||||||
this.item = item
|
this.item = item
|
||||||
this.variant = variant
|
this.variant = variant
|
||||||
},
|
},
|
||||||
updateState(id) {
|
updateStatus(id) {
|
||||||
this.pendingCreations.find((obj) => obj.id === id).messagesCount++
|
this.items.find((obj) => obj.id === id).messagesCount++
|
||||||
this.pendingCreations.find((obj) => obj.id === id).state = 'IN_PROGRESS'
|
this.items.find((obj) => obj.id === id).state = 'IN_PROGRESS'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
statusFilter() {
|
||||||
|
this.$apollo.queries.ListAllContributions.refetch()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
fields() {
|
fields() {
|
||||||
return [
|
return [
|
||||||
{ key: 'bookmark', label: this.$t('delete') },
|
[
|
||||||
{ key: 'deny', label: this.$t('deny') },
|
{ key: 'bookmark', label: this.$t('delete') },
|
||||||
{ key: 'email', label: this.$t('e_mail') },
|
{ key: 'deny', label: this.$t('deny') },
|
||||||
{ key: 'firstName', label: this.$t('firstname') },
|
{ key: 'email', label: this.$t('e_mail') },
|
||||||
{ key: 'lastName', label: this.$t('lastname') },
|
{ key: 'firstName', label: this.$t('firstname') },
|
||||||
{
|
{ key: 'lastName', label: this.$t('lastname') },
|
||||||
key: 'amount',
|
{
|
||||||
label: this.$t('creation'),
|
key: 'amount',
|
||||||
formatter: (value) => {
|
label: this.$t('creation'),
|
||||||
return value + ' GDD'
|
formatter: (value) => {
|
||||||
|
return value + ' GDD'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{ key: 'memo', label: this.$t('text'), class: 'text-break' },
|
||||||
{ key: 'memo', label: this.$t('text'), class: 'text-break' },
|
{
|
||||||
{
|
key: 'contributionDate',
|
||||||
key: 'date',
|
label: this.$t('created'),
|
||||||
label: this.$t('date'),
|
formatter: (value) => {
|
||||||
formatter: (value) => {
|
return this.$d(new Date(value), 'short')
|
||||||
return this.$d(new Date(value), 'short')
|
},
|
||||||
},
|
},
|
||||||
},
|
{ key: 'moderator', label: this.$t('moderator') },
|
||||||
{ key: 'moderator', label: this.$t('moderator') },
|
{ key: 'editCreation', label: this.$t('edit') },
|
||||||
{ key: 'editCreation', label: this.$t('edit') },
|
{ key: 'confirm', label: this.$t('save') },
|
||||||
{ key: 'confirm', label: this.$t('save') },
|
],
|
||||||
]
|
[
|
||||||
|
{ key: 'firstName', label: this.$t('firstname') },
|
||||||
|
{ key: 'lastName', label: this.$t('lastname') },
|
||||||
|
{
|
||||||
|
key: 'amount',
|
||||||
|
label: this.$t('creation'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return value + ' GDD'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ key: 'memo', label: this.$t('text'), class: 'text-break' },
|
||||||
|
{
|
||||||
|
key: 'contributionDate',
|
||||||
|
label: this.$t('created'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return this.$d(new Date(value), 'short')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'createdAt',
|
||||||
|
label: this.$t('createdAt'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return this.$d(new Date(value), 'short')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'confirmedAt',
|
||||||
|
label: this.$t('contributions.confirms'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return this.$d(new Date(value), 'short')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ key: 'chatCreation', label: this.$t('chat') },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ key: 'reActive', label: 'reActive' },
|
||||||
|
{ key: 'firstName', label: this.$t('firstname') },
|
||||||
|
{ key: 'lastName', label: this.$t('lastname') },
|
||||||
|
{
|
||||||
|
key: 'amount',
|
||||||
|
label: this.$t('creation'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return value + ' GDD'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ key: 'memo', label: this.$t('text'), class: 'text-break' },
|
||||||
|
{
|
||||||
|
key: 'contributionDate',
|
||||||
|
label: this.$t('created'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return this.$d(new Date(value), 'short')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'createdAt',
|
||||||
|
label: this.$t('createdAt'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return this.$d(new Date(value), 'short')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'deniedAt',
|
||||||
|
label: this.$t('contributions.denied'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return this.$d(new Date(value), 'short')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ key: 'deniedBy', label: this.$t('mod') },
|
||||||
|
{ key: 'chatCreation', label: this.$t('chat') },
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
{ key: 'state', label: 'state' },
|
||||||
|
{ key: 'firstName', label: this.$t('firstname') },
|
||||||
|
{ key: 'lastName', label: this.$t('lastname') },
|
||||||
|
{
|
||||||
|
key: 'amount',
|
||||||
|
label: this.$t('creation'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return value + ' GDD'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ key: 'memo', label: this.$t('text'), class: 'text-break' },
|
||||||
|
{
|
||||||
|
key: 'contributionDate',
|
||||||
|
label: this.$t('created'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return this.$d(new Date(value), 'short')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'createdAt',
|
||||||
|
label: this.$t('createdAt'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return this.$d(new Date(value), 'short')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'confirmedAt',
|
||||||
|
label: this.$t('contributions.confirms'),
|
||||||
|
formatter: (value) => {
|
||||||
|
return this.$d(new Date(value), 'short')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ key: 'confirmedBy', label: this.$t('mod') },
|
||||||
|
{ key: 'chatCreation', label: this.$t('chat') },
|
||||||
|
],
|
||||||
|
][this.tabIndex]
|
||||||
|
},
|
||||||
|
statusFilter() {
|
||||||
|
return FILTER_TAB_MAP[this.tabIndex]
|
||||||
},
|
},
|
||||||
overlayTitle() {
|
overlayTitle() {
|
||||||
return `overlay.${this.variant}.title`
|
return `overlay.${this.variant}.title`
|
||||||
@ -182,18 +347,21 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
PendingContributions: {
|
ListAllContributions: {
|
||||||
query() {
|
query() {
|
||||||
return listUnconfirmedContributions
|
return listAllContributions
|
||||||
},
|
},
|
||||||
variables() {
|
variables() {
|
||||||
// may be at some point we need a pagination here
|
// may be at some point we need a pagination here
|
||||||
return {}
|
return {
|
||||||
|
currentPage: this.currentPage,
|
||||||
|
pageSize: this.pageSize,
|
||||||
|
statusFilter: this.statusFilter,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
update({ listUnconfirmedContributions }) {
|
update({ listAllContributions }) {
|
||||||
this.$store.commit('resetOpenCreations')
|
this.rows = listAllContributions.contributionCount
|
||||||
this.pendingCreations = listUnconfirmedContributions
|
this.items = listAllContributions.contributionList
|
||||||
this.$store.commit('setOpenCreations', listUnconfirmedContributions.length)
|
|
||||||
},
|
},
|
||||||
error({ message }) {
|
error({ message }) {
|
||||||
this.toastError(message)
|
this.toastError(message)
|
||||||
|
|||||||
@ -1,41 +1,18 @@
|
|||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import Overview from './Overview.vue'
|
import Overview from './Overview.vue'
|
||||||
import { listUnconfirmedContributions } from '@/graphql/listUnconfirmedContributions.js'
|
import { listAllContributions } from '../graphql/listAllContributions'
|
||||||
|
import VueApollo from 'vue-apollo'
|
||||||
|
import { createMockClient } from 'mock-apollo-client'
|
||||||
|
import { toastErrorSpy } from '../../test/testSetup'
|
||||||
|
|
||||||
|
const mockClient = createMockClient()
|
||||||
|
const apolloProvider = new VueApollo({
|
||||||
|
defaultClient: mockClient,
|
||||||
|
})
|
||||||
|
|
||||||
const localVue = global.localVue
|
const localVue = global.localVue
|
||||||
|
|
||||||
const apolloQueryMock = jest
|
localVue.use(VueApollo)
|
||||||
.fn()
|
|
||||||
.mockResolvedValueOnce({
|
|
||||||
data: {
|
|
||||||
listUnconfirmedContributions: [
|
|
||||||
{
|
|
||||||
pending: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pending: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pending: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.mockResolvedValue({
|
|
||||||
data: {
|
|
||||||
listUnconfirmedContributions: [
|
|
||||||
{
|
|
||||||
pending: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pending: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pending: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const storeCommitMock = jest.fn()
|
const storeCommitMock = jest.fn()
|
||||||
|
|
||||||
@ -43,44 +20,114 @@ const mocks = {
|
|||||||
$t: jest.fn((t) => t),
|
$t: jest.fn((t) => t),
|
||||||
$n: jest.fn((n) => n),
|
$n: jest.fn((n) => n),
|
||||||
$d: jest.fn((d) => d),
|
$d: jest.fn((d) => d),
|
||||||
$apollo: {
|
|
||||||
query: apolloQueryMock,
|
|
||||||
},
|
|
||||||
$store: {
|
$store: {
|
||||||
commit: storeCommitMock,
|
commit: storeCommitMock,
|
||||||
state: {
|
state: {
|
||||||
openCreations: 2,
|
openCreations: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultData = () => {
|
||||||
|
return {
|
||||||
|
listAllContributions: {
|
||||||
|
contributionCount: 2,
|
||||||
|
contributionList: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
firstName: 'Bibi',
|
||||||
|
lastName: 'Bloxberg',
|
||||||
|
userId: 99,
|
||||||
|
email: 'bibi@bloxberg.de',
|
||||||
|
amount: 500,
|
||||||
|
memo: 'Danke für alles',
|
||||||
|
date: new Date(),
|
||||||
|
moderator: 1,
|
||||||
|
state: 'PENDING',
|
||||||
|
creation: [500, 500, 500],
|
||||||
|
messagesCount: 0,
|
||||||
|
deniedBy: null,
|
||||||
|
deniedAt: null,
|
||||||
|
confirmedBy: null,
|
||||||
|
confirmedAt: null,
|
||||||
|
contributionDate: new Date(),
|
||||||
|
deletedBy: null,
|
||||||
|
deletedAt: null,
|
||||||
|
createdAt: new Date(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
firstName: 'Räuber',
|
||||||
|
lastName: 'Hotzenplotz',
|
||||||
|
userId: 100,
|
||||||
|
email: 'raeuber@hotzenplotz.de',
|
||||||
|
amount: 1000000,
|
||||||
|
memo: 'Gut Ergattert',
|
||||||
|
date: new Date(),
|
||||||
|
moderator: 1,
|
||||||
|
state: 'PENDING',
|
||||||
|
creation: [500, 500, 500],
|
||||||
|
messagesCount: 0,
|
||||||
|
deniedBy: null,
|
||||||
|
deniedAt: null,
|
||||||
|
confirmedBy: null,
|
||||||
|
confirmedAt: null,
|
||||||
|
contributionDate: new Date(),
|
||||||
|
deletedBy: null,
|
||||||
|
deletedAt: null,
|
||||||
|
createdAt: new Date(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
describe('Overview', () => {
|
describe('Overview', () => {
|
||||||
let wrapper
|
let wrapper
|
||||||
|
const listAllContributionsMock = jest.fn()
|
||||||
|
|
||||||
|
mockClient.setRequestHandler(
|
||||||
|
listAllContributions,
|
||||||
|
listAllContributionsMock
|
||||||
|
.mockRejectedValueOnce({ message: 'Ouch!' })
|
||||||
|
.mockResolvedValue({ data: defaultData() }),
|
||||||
|
)
|
||||||
|
|
||||||
const Wrapper = () => {
|
const Wrapper = () => {
|
||||||
return mount(Overview, { localVue, mocks })
|
return mount(Overview, { localVue, mocks, apolloProvider })
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('mount', () => {
|
describe('mount', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
wrapper = Wrapper()
|
wrapper = Wrapper()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('calls listUnconfirmedContributions', () => {
|
describe('server response for get pending creations is error', () => {
|
||||||
expect(apolloQueryMock).toBeCalledWith(
|
it('toast an error message', () => {
|
||||||
expect.objectContaining({
|
expect(toastErrorSpy).toBeCalledWith('Ouch!')
|
||||||
query: listUnconfirmedContributions,
|
})
|
||||||
}),
|
})
|
||||||
)
|
|
||||||
|
it('calls the listAllContributions query', () => {
|
||||||
|
expect(listAllContributionsMock).toBeCalledWith({
|
||||||
|
currentPage: 1,
|
||||||
|
order: 'DESC',
|
||||||
|
pageSize: 25,
|
||||||
|
statusFilter: ['IN_PROGRESS', 'PENDING'],
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('commits three pending creations to store', () => {
|
it('commits three pending creations to store', () => {
|
||||||
expect(storeCommitMock).toBeCalledWith('setOpenCreations', 3)
|
expect(storeCommitMock).toBeCalledWith('setOpenCreations', 2)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('with open creations', () => {
|
describe('with open creations', () => {
|
||||||
it('renders a link to confirm creations', () => {
|
beforeEach(() => {
|
||||||
expect(wrapper.find('a[href="creation-confirm"]').text()).toContain('2')
|
mocks.$store.state.openCreations = 2
|
||||||
|
})
|
||||||
|
it('renders a link to confirm 2 creations', () => {
|
||||||
|
expect(wrapper.find('[data-test="open-creation"]').text()).toContain('2')
|
||||||
expect(wrapper.find('a[href="creation-confirm"]').exists()).toBeTruthy()
|
expect(wrapper.find('a[href="creation-confirm"]').exists()).toBeTruthy()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -91,7 +138,7 @@ describe('Overview', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('renders a link to confirm creations', () => {
|
it('renders a link to confirm creations', () => {
|
||||||
expect(wrapper.find('a[href="creation-confirm"]').text()).toContain('0')
|
expect(wrapper.find('[data-test="open-creation"]').text()).toContain('0')
|
||||||
expect(wrapper.find('a[href="creation-confirm"]').exists()).toBeTruthy()
|
expect(wrapper.find('a[href="creation-confirm"]').exists()).toBeTruthy()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -24,31 +24,40 @@
|
|||||||
>
|
>
|
||||||
<b-card-text>
|
<b-card-text>
|
||||||
<b-link to="creation-confirm">
|
<b-link to="creation-confirm">
|
||||||
<h1>{{ $store.state.openCreations }}</h1>
|
<h1 data-test="open-creation">{{ $store.state.openCreations }}</h1>
|
||||||
</b-link>
|
</b-link>
|
||||||
</b-card-text>
|
</b-card-text>
|
||||||
</b-card>
|
</b-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { listUnconfirmedContributions } from '@/graphql/listUnconfirmedContributions.js'
|
import { listAllContributions } from '../graphql/listAllContributions'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'overview',
|
name: 'overview',
|
||||||
methods: {
|
data() {
|
||||||
getPendingCreations() {
|
return {
|
||||||
this.$apollo
|
statusFilter: ['IN_PROGRESS', 'PENDING'],
|
||||||
.query({
|
}
|
||||||
query: listUnconfirmedContributions,
|
|
||||||
fetchPolicy: 'network-only',
|
|
||||||
})
|
|
||||||
.then((result) => {
|
|
||||||
this.$store.commit('setOpenCreations', result.data.listUnconfirmedContributions.length)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
created() {
|
apollo: {
|
||||||
this.getPendingCreations()
|
AllContributions: {
|
||||||
|
query() {
|
||||||
|
return listAllContributions
|
||||||
|
},
|
||||||
|
variables() {
|
||||||
|
// may be at some point we need a pagination here
|
||||||
|
return {
|
||||||
|
statusFilter: this.statusFilter,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
update({ listAllContributions }) {
|
||||||
|
this.$store.commit('setOpenCreations', listAllContributions.contributionCount)
|
||||||
|
},
|
||||||
|
error({ message }) {
|
||||||
|
this.toastError(message)
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -181,6 +181,7 @@ export class ContributionResolver {
|
|||||||
.select('c')
|
.select('c')
|
||||||
.from(DbContribution, 'c')
|
.from(DbContribution, 'c')
|
||||||
.innerJoinAndSelect('c.user', 'u')
|
.innerJoinAndSelect('c.user', 'u')
|
||||||
|
.leftJoinAndSelect('c.messages', 'm')
|
||||||
.where(where)
|
.where(where)
|
||||||
.orderBy('c.createdAt', order)
|
.orderBy('c.createdAt', order)
|
||||||
.limit(pageSize)
|
.limit(pageSize)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user