Merge branch 'master' into 1078-GDD-Calculate-Decay-Tool-clear

This commit is contained in:
Alexander Friedland 2021-12-06 10:00:49 +01:00 committed by GitHub
commit ff94905ede
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 217 additions and 105 deletions

View File

@ -441,7 +441,7 @@ jobs:
report_name: Coverage Admin Interface
type: lcov
result_path: ./coverage/lcov.info
min_coverage: 50
min_coverage: 52
token: ${{ github.token }}
##############################################################################

View File

@ -0,0 +1,7 @@
import gql from 'graphql-tag'
export const countPendingCreations = gql`
query {
countPendingCreations
}
`

View File

@ -0,0 +1,16 @@
import gql from 'graphql-tag'
export const getPendingCreations = gql`
query {
getPendingCreations {
firstName
lastName
email
amount
memo
date
moderator
creation
}
}
`

View File

@ -4,11 +4,47 @@ import CreationConfirm from './CreationConfirm.vue'
const localVue = global.localVue
const storeCommitMock = jest.fn()
const toastedErrorMock = jest.fn()
const apolloQueryMock = jest.fn().mockResolvedValue({
data: {
getPendingCreations: [
{
firstName: 'Bibi',
lastName: 'Bloxberg',
email: 'bibi@bloxberg.de',
amount: 500,
memo: 'Danke für alles',
date: new Date(),
moderator: 0,
},
{
firstName: 'Räuber',
lastName: 'Hotzenplotz',
email: 'raeuber@hotzenplotz.de',
amount: 1000000,
memo: 'Gut Ergatert',
date: new Date(),
moderator: 0,
},
],
},
})
const mocks = {
$store: {
commit: storeCommitMock,
},
$apollo: {
query: apolloQueryMock,
},
$toasted: {
error: toastedErrorMock,
},
$moment: jest.fn((value) => {
return {
format: jest.fn((format) => value),
}
}),
}
describe('CreationConfirm', () => {
@ -32,9 +68,22 @@ describe('CreationConfirm', () => {
it('commits resetOpenCreations to store', () => {
expect(storeCommitMock).toBeCalledWith('resetOpenCreations')
})
it('commits setOpenCreations to store', () => {
expect(storeCommitMock).toBeCalledWith('setOpenCreations', 2)
})
})
it('commits openCreationsPlus to store', () => {
expect(storeCommitMock).toBeCalledWith('openCreationsPlus', 5)
describe('server response is error', () => {
beforeEach(() => {
jest.clearAllMocks()
apolloQueryMock.mockRejectedValue({
message: 'Ouch!',
})
wrapper = Wrapper()
})
it('toast an error message', () => {
expect(toastedErrorMock).toBeCalledWith('Ouch!')
})
})

View File

@ -1,9 +1,5 @@
<template>
<div class="creation-confirm">
<small class="bg-danger text-light p-1">
Die anzahl der offene Schöpfungen stimmen nicht! Diese wird bei absenden im $store
hochgezählt. Die Liste die hier angezeigt wird ist SIMULIERT!
</small>
<user-table
class="mt-4"
type="PageCreationConfirm"
@ -15,6 +11,7 @@
</template>
<script>
import UserTable from '../components/UserTable.vue'
import { getPendingCreations } from '../graphql/getPendingCreations'
export default {
name: 'CreationConfirm',
@ -30,98 +27,25 @@ export default {
{ key: 'firstName', label: 'Vorname' },
{ key: 'lastName', label: 'Nachname' },
{
key: 'creation_gdd',
key: 'amount',
label: 'Schöpfung',
formatter: (value) => {
return value + ' GDD'
},
},
{ key: 'text', label: 'Text' },
{ key: 'memo', label: 'Text' },
{
key: 'creation_date',
key: 'date',
label: 'Datum',
formatter: (value) => {
return value.long
return this.$moment(value).format('ll')
},
},
{ key: 'creation_moderator', label: 'Moderator' },
{ key: 'moderator', label: 'Moderator' },
{ key: 'edit_creation', label: 'ändern' },
{ key: 'confirm', label: 'speichern' },
],
confirmResult: [
{
id: 1,
email: 'dickerson@web.de',
firstName: 'Dickerson',
lastName: 'Macdonald',
creation: '[450,200,700]',
creation_gdd: '1000',
text: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam ',
creation_date: {
short: 'November',
long: '22/11/2021',
},
creation_moderator: 'Manuela Gast',
},
{
id: 2,
email: 'larsen@woob.de',
firstName: 'Larsen',
lastName: 'Shaw',
creation: '[300,200,1000]',
creation_gdd: '1000',
text: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam ',
creation_date: {
short: 'November',
long: '03/11/2021',
},
creation_moderator: 'Manuela Gast',
},
{
id: 3,
email: 'geneva@tete.de',
firstName: 'Geneva',
lastName: 'Wilson',
creation: '[350,200,900]',
creation_gdd: '1000',
text: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam',
creation_date: {
short: 'September',
long: '27/09/2021',
},
creation_moderator: 'Manuela Gast',
},
{
id: 4,
email: 'viewrter@asdfvb.com',
firstName: 'Soledare',
lastName: 'Takker',
creation: '[100,400,800]',
creation_gdd: '500',
text: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo ',
creation_date: {
short: 'Oktober',
long: '12/10/2021',
},
creation_moderator: 'Evelyn Roller',
},
{
id: 5,
email: 'dickerson@web.de',
firstName: 'Dickerson',
lastName: 'Macdonald',
creation: '[100,400,800]',
creation_gdd: '200',
text: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At',
creation_date: {
short: 'September',
long: '05/09/2021',
},
creation_moderator: 'Manuela Gast',
},
],
confirmResult: [],
}
},
@ -140,10 +64,23 @@ export default {
this.$store.commit('openCreationsMinus', 1)
}
},
getPendingCreations() {
this.$apollo
.query({
query: getPendingCreations,
})
.then((result) => {
this.$store.commit('resetOpenCreations')
this.confirmResult = result.data.getPendingCreations.reverse()
this.$store.commit('setOpenCreations', result.data.getPendingCreations.length)
})
.catch((error) => {
this.$toasted.error(error.message)
})
},
},
created() {
this.$store.commit('resetOpenCreations')
this.$store.commit('openCreationsPlus', Object.keys(this.confirmResult).length)
async created() {
await this.getPendingCreations()
},
}
</script>

View File

@ -76,7 +76,24 @@
</div>
</template>
<script>
import { getPendingCreations } from '../graphql/getPendingCreations'
export default {
name: 'overview',
methods: {
getPendingCreations() {
this.$apollo
.query({
query: getPendingCreations,
})
.then((result) => {
this.$store.commit('setOpenCreations', result.data.getPendingCreations.length)
})
.catch()
},
},
created() {
this.getPendingCreations()
},
}
</script>

View File

@ -18,6 +18,9 @@ export const mutations = {
token: (state, token) => {
state.token = token
},
setOpenCreations: (state, openCreations) => {
state.openCreations = openCreations
},
moderator: (state, moderator) => {
state.moderator = moderator
},

View File

@ -1,11 +1,13 @@
import store, { mutations, actions } from './store'
import CONFIG from '../config'
const { token, openCreationsPlus, openCreationsMinus, resetOpenCreations } = mutations
jest.mock('../config')
const { token, openCreationsPlus, openCreationsMinus, resetOpenCreations, setOpenCreations } =
mutations
const { logout } = actions
const CONFIG = {
DEBUG_DISABLE_AUTH: true,
}
CONFIG.DEBUG_DISABLE_AUTH = true
describe('Vuex store', () => {
describe('mutations', () => {
@ -40,6 +42,14 @@ describe('Vuex store', () => {
expect(state.openCreations).toEqual(0)
})
})
describe('setOpenCreations', () => {
it('sets the open creations to given value', () => {
const state = { openCreations: 24 }
setOpenCreations(state, 12)
expect(state.openCreations).toEqual(12)
})
})
})
describe('actions', () => {

View File

@ -0,0 +1,34 @@
import { ObjectType, Field, Int } from 'type-graphql'
@ObjectType()
export class PendingCreation {
@Field(() => String)
firstName: string
@Field(() => Int)
id?: number
@Field(() => String)
lastName: string
@Field(() => Number)
userId: number
@Field(() => String)
email: string
@Field(() => Date)
date: Date
@Field(() => String)
memo: string
@Field(() => Number)
amount: BigInt
@Field(() => Number)
moderator: number
@Field(() => [Number])
creation: number[]
}

View File

@ -1,7 +1,7 @@
import { Resolver, Query, Arg, Args, Authorized, Mutation } from 'type-graphql'
import { getCustomRepository, Raw } from 'typeorm'
import { UserAdmin } from '../model/UserAdmin'
import { LoginUserRepository } from '../../typeorm/repository/LoginUser'
import { PendingCreation } from '../model/PendingCreation'
import { RIGHTS } from '../../auth/RIGHTS'
import { TransactionCreationRepository } from '../../typeorm/repository/TransactionCreation'
import { PendingCreationRepository } from '../../typeorm/repository/PendingCreation'
@ -14,19 +14,19 @@ export class AdminResolver {
@Authorized([RIGHTS.SEARCH_USERS])
@Query(() => [UserAdmin])
async searchUsers(@Arg('searchText') searchText: string): Promise<UserAdmin[]> {
const loginUserRepository = getCustomRepository(LoginUserRepository)
const loginUsers = await loginUserRepository.findBySearchCriteria(searchText)
const users = await Promise.all(
loginUsers.map(async (loginUser) => {
const user = new UserAdmin()
user.firstName = loginUser.firstName
user.lastName = loginUser.lastName
user.email = loginUser.email
user.creation = await getUserCreations(loginUser.id)
return user
const userRepository = getCustomRepository(UserRepository)
const users = await userRepository.findBySearchCriteria(searchText)
const adminUsers = await Promise.all(
users.map(async (user) => {
const adminUser = new UserAdmin()
adminUser.firstName = user.firstName
adminUser.lastName = user.lastName
adminUser.email = user.email
adminUser.creation = await getUserCreations(user.id)
return adminUser
}),
)
return users
return adminUsers
}
@Mutation(() => [Number])
@ -52,6 +52,30 @@ export class AdminResolver {
}
return await getUserCreations(user.id)
}
@Query(() => [PendingCreation])
async getPendingCreations(): Promise<PendingCreation[]> {
const pendingCreationRepository = getCustomRepository(PendingCreationRepository)
const pendingCreations = await pendingCreationRepository.find()
const pendingCreationsPromise = await Promise.all(
pendingCreations.map(async (pendingCreation) => {
const userRepository = getCustomRepository(UserRepository)
const user = await userRepository.findOneOrFail({ id: pendingCreation.userId })
const newPendingCreation = {
...pendingCreation,
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
creation: await getUserCreations(user.id),
}
return newPendingCreation
}),
)
return pendingCreationsPromise
}
}
async function getUserCreations(id: number): Promise<number[]> {

View File

@ -30,4 +30,17 @@ export class UserRepository extends Repository<User> {
})
return usersIndiced
}
async findBySearchCriteria(searchCriteria: string): Promise<User[]> {
return await this.createQueryBuilder('user')
.where(
'user.firstName like :name or user.lastName like :lastName or user.email like :email',
{
name: `%${searchCriteria}%`,
lastName: `%${searchCriteria}%`,
email: `%${searchCriteria}%`,
},
)
.getMany()
}
}

View File

@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/*
Elopage Webhook