Merge branch 'master' into iota5_dlt-database

This commit is contained in:
einhornimmond 2023-08-30 22:22:19 +02:00 committed by GitHub
commit e466bb7a8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 197 additions and 81 deletions

View File

@ -7,9 +7,13 @@ import { IsPositiveDecimal } from '@/graphql/validator/Decimal'
@ArgsType()
export class TransactionSendArgs {
@Field(() => String, { nullable: true })
@IsString()
recipientCommunityIdentifier?: string | null | undefined
@Field(() => String)
@IsString()
identifier: string
recipientIdentifier: string
@Field(() => Decimal)
@IsPositiveDecimal()

View File

@ -12,7 +12,7 @@ import { ApolloServerTestClient } from 'apollo-server-testing'
import { cleanDB, testEnvironment } from '@test/helpers'
import { getCommunities, getCommunitySelections } from '@/seeds/graphql/queries'
import { getCommunities, communities } from '@/seeds/graphql/queries'
// to do: We need a setup for the tests that closes the connection
let query: ApolloServerTestClient['query'], con: Connection
@ -234,7 +234,7 @@ describe('CommunityResolver', () => {
})
})
describe('getCommunitySelections', () => {
describe('communities', () => {
let homeCom1: DbCommunity
let foreignCom1: DbCommunity
let foreignCom2: DbCommunity
@ -248,9 +248,9 @@ describe('CommunityResolver', () => {
it('returns no community entry', async () => {
// const result: Community[] = await query({ query: getCommunities })
// expect(result.length).toEqual(0)
await expect(query({ query: getCommunitySelections })).resolves.toMatchObject({
await expect(query({ query: communities })).resolves.toMatchObject({
data: {
getCommunitySelections: [],
communities: [],
},
})
})
@ -275,9 +275,9 @@ describe('CommunityResolver', () => {
})
it('returns 1 home-community entry', async () => {
await expect(query({ query: getCommunitySelections })).resolves.toMatchObject({
await expect(query({ query: communities })).resolves.toMatchObject({
data: {
getCommunitySelections: [
communities: [
{
id: expect.any(Number),
foreign: homeCom1.foreign,
@ -337,9 +337,9 @@ describe('CommunityResolver', () => {
})
it('returns 3 community entries', async () => {
await expect(query({ query: getCommunitySelections })).resolves.toMatchObject({
await expect(query({ query: communities })).resolves.toMatchObject({
data: {
getCommunitySelections: [
communities: [
{
id: expect.any(Number),
foreign: homeCom1.foreign,

View File

@ -26,7 +26,7 @@ export class CommunityResolver {
@Authorized([RIGHTS.COMMUNITIES])
@Query(() => [Community])
async getCommunitySelections(): Promise<Community[]> {
async communities(): Promise<Community[]> {
const dbCommunities: DbCommunity[] = await DbCommunity.find({
order: {
name: 'ASC',

View File

@ -91,7 +91,7 @@ describe('send coins', () => {
await mutate({
mutation: sendCoins,
variables: {
identifier: 'wrong@email.com',
recipientIdentifier: 'wrong@email.com',
amount: 100,
memo: 'test test',
},
@ -119,7 +119,7 @@ describe('send coins', () => {
await mutate({
mutation: sendCoins,
variables: {
identifier: 'stephen@hawking.uk',
recipientIdentifier: 'stephen@hawking.uk',
amount: 100,
memo: 'test test',
},
@ -148,7 +148,7 @@ describe('send coins', () => {
await mutate({
mutation: sendCoins,
variables: {
identifier: 'garrick@ollivander.com',
recipientIdentifier: 'garrick@ollivander.com',
amount: 100,
memo: 'test test',
},
@ -184,7 +184,7 @@ describe('send coins', () => {
await mutate({
mutation: sendCoins,
variables: {
identifier: 'bob@baumeister.de',
recipientIdentifier: 'bob@baumeister.de',
amount: 100,
memo: 'test test',
},
@ -207,7 +207,7 @@ describe('send coins', () => {
const { errors: errorObjects } = await mutate({
mutation: sendCoins,
variables: {
identifier: 'peter@lustig.de',
recipientIdentifier: 'peter@lustig.de',
amount: 100,
memo: 'Test',
},
@ -238,7 +238,7 @@ describe('send coins', () => {
const { errors: errorObjects } = await mutate({
mutation: sendCoins,
variables: {
identifier: 'peter@lustig.de',
recipientIdentifier: 'peter@lustig.de',
amount: 100,
memo: 'test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test t',
},
@ -270,7 +270,7 @@ describe('send coins', () => {
await mutate({
mutation: sendCoins,
variables: {
identifier: 'peter@lustig.de',
recipientIdentifier: 'peter@lustig.de',
amount: 100,
memo: 'testing',
},
@ -319,7 +319,7 @@ describe('send coins', () => {
const { errors: errorObjects } = await mutate({
mutation: sendCoins,
variables: {
identifier: 'peter@lustig.de',
recipientIdentifier: 'peter@lustig.de',
amount: -50,
memo: 'testing negative',
},
@ -350,7 +350,7 @@ describe('send coins', () => {
await mutate({
mutation: sendCoins,
variables: {
identifier: 'peter@lustig.de',
recipientIdentifier: 'peter@lustig.de',
amount: 50,
memo: 'unrepeatable memo',
},
@ -456,7 +456,7 @@ describe('send coins', () => {
mutate({
mutation: sendCoins,
variables: {
identifier: peter?.gradidoID,
recipientIdentifier: peter?.gradidoID,
amount: 10,
memo: 'send via gradido ID',
},
@ -496,7 +496,7 @@ describe('send coins', () => {
mutate({
mutation: sendCoins,
variables: {
identifier: 'bob',
recipientIdentifier: 'bob',
amount: 6.66,
memo: 'send via alias',
},
@ -564,7 +564,7 @@ describe('send coins', () => {
mutate({
mutation: sendCoins,
variables: {
identifier: 'peter@lustig.de',
recipientIdentifier: 'peter@lustig.de',
amount: 10,
memo: 'first transaction',
},
@ -580,7 +580,7 @@ describe('send coins', () => {
mutate({
mutation: sendCoins,
variables: {
identifier: 'peter@lustig.de',
recipientIdentifier: 'peter@lustig.de',
amount: 20,
memo: 'second transaction',
},
@ -596,7 +596,7 @@ describe('send coins', () => {
mutate({
mutation: sendCoins,
variables: {
identifier: 'peter@lustig.de',
recipientIdentifier: 'peter@lustig.de',
amount: 30,
memo: 'third transaction',
},
@ -612,7 +612,7 @@ describe('send coins', () => {
mutate({
mutation: sendCoins,
variables: {
identifier: 'peter@lustig.de',
recipientIdentifier: 'peter@lustig.de',
amount: 40,
memo: 'fourth transaction',
},

View File

@ -308,15 +308,18 @@ export class TransactionResolver {
@Authorized([RIGHTS.SEND_COINS])
@Mutation(() => Boolean)
async sendCoins(
@Args() { identifier, amount, memo }: TransactionSendArgs,
@Args()
{ /* recipientCommunityIdentifier, */ recipientIdentifier, amount, memo }: TransactionSendArgs,
@Ctx() context: Context,
): Promise<boolean> {
logger.info(`sendCoins(identifier=${identifier}, amount=${amount}, memo=${memo})`)
logger.info(
`sendCoins(recipientIdentifier=${recipientIdentifier}, amount=${amount}, memo=${memo})`,
)
const senderUser = getUser(context)
// validate recipient user
const recipientUser = await findUserByIdentifier(identifier)
const recipientUser = await findUserByIdentifier(recipientIdentifier)
if (!recipientUser) {
throw new LogError('The recipient user was not found', recipientUser)
}

View File

@ -156,7 +156,11 @@ describe('semaphore', () => {
})
const bibisTransaction = mutate({
mutation: sendCoins,
variables: { identifier: 'bob@baumeister.de', amount: '50', memo: 'Das ist für dich, Bob' },
variables: {
recipientIdentifier: 'bob@baumeister.de',
amount: '50',
memo: 'Das ist für dich, Bob',
},
})
await mutate({
mutation: login,
@ -172,7 +176,11 @@ describe('semaphore', () => {
})
const bobsTransaction = mutate({
mutation: sendCoins,
variables: { identifier: 'bibi@bloxberg.de', amount: '50', memo: 'Das ist für dich, Bibi' },
variables: {
recipientIdentifier: 'bibi@bloxberg.de',
amount: '50',
memo: 'Das ist für dich, Bibi',
},
})
await mutate({
mutation: login,

View File

@ -79,8 +79,8 @@ export const sendActivationEmail = gql`
`
export const sendCoins = gql`
mutation ($identifier: String!, $amount: Decimal!, $memo: String!) {
sendCoins(identifier: $identifier, amount: $amount, memo: $memo)
mutation ($recipientIdentifier: String!, $amount: Decimal!, $memo: String!) {
sendCoins(recipientIdentifier: $recipientIdentifier, amount: $amount, memo: $memo)
}
`

View File

@ -118,25 +118,17 @@ export const listGDTEntriesQuery = gql`
}
`
export const communityInfo = gql`
query {
getCommunityInfo {
name
description
registerUrl
url
}
}
`
export const communities = gql`
query {
communities {
id
foreign
name
url
description
registerUrl
url
creationDate
uuid
authenticatedAt
}
}
`
@ -157,21 +149,6 @@ export const getCommunities = gql`
}
`
export const getCommunitySelections = gql`
query {
getCommunitySelections {
id
foreign
name
description
url
creationDate
uuid
authenticatedAt
}
}
`
export const queryTransactionLink = gql`
query ($code: String!) {
queryTransactionLink(code: $code) {

View File

@ -49,8 +49,13 @@ When('the user submits the transaction by confirming', () => {
cy.wrap(interception.request.body).should(
'have.property',
'query',
`mutation ($identifier: String!, $amount: Decimal!, $memo: String!) {
sendCoins(identifier: $identifier, amount: $amount, memo: $memo)
`mutation ($recipientCommunityIdentifier: String!, $recipientIdentifier: String!, $amount: Decimal!, $memo: String!) {
sendCoins(
recipientCommunityIdentifier: $recipientCommunityIdentifier
recipientIdentifier: $recipientIdentifier
amount: $amount
memo: $memo
)
}
`,
)

View File

@ -0,0 +1,58 @@
<template>
<div class="community-switch">
<b-dropdown no-flip :text="value.name">
<b-dropdown-item
v-for="community in communities"
@click.prevent="updateCommunity(community)"
:key="community.id"
:title="community.description"
:active="value.uuid === community.uuid"
>
{{ community.name }}
</b-dropdown-item>
</b-dropdown>
</div>
</template>
<script>
import { selectCommunities } from '@/graphql/queries'
export default {
name: 'CommunitySwitch',
props: {
value: {
type: Object,
},
},
data() {
return {
communities: [],
}
},
methods: {
updateCommunity(community) {
this.$emit('input', community)
},
setDefaultCommunity() {
// set default community, the only one which isn't foreign
// we assume it is only one entry with foreign = false
if (this.value.uuid === '' && this.communities.length) {
const foundCommunity = this.communities.find((community) => !community.foreign)
if (foundCommunity) {
this.updateCommunity(foundCommunity)
}
}
},
},
apollo: {
communities: {
query: selectCommunities,
},
},
mounted() {
this.setDefaultCommunity()
},
updated() {
this.setDefaultCommunity()
},
}
</script>

View File

@ -6,7 +6,7 @@
<b-col cols="12">
<b-row class="mt-3">
<b-col class="h5">{{ $t('form.recipientCommunity') }}</b-col>
<b-col>{{ communityName }}</b-col>
<b-col>{{ targetCommunity.name }}</b-col>
</b-row>
<b-row>
<b-col class="h5">{{ $t('form.recipient') }}</b-col>
@ -76,11 +76,16 @@ export default {
amount: { type: Number, required: true },
memo: { type: String, required: true },
userName: { type: String, default: '' },
targetCommunity: {
type: Object,
default: function () {
return { uuid: '', name: COMMUNITY_NAME }
},
},
},
data() {
return {
disabled: false,
communityName: COMMUNITY_NAME,
}
},
}

View File

@ -4,7 +4,7 @@ import flushPromises from 'flush-promises'
import { SEND_TYPES } from '@/pages/Send'
import { createMockClient } from 'mock-apollo-client'
import VueApollo from 'vue-apollo'
import { user as userQuery } from '@/graphql/queries'
import { user as userQuery, selectCommunities as selectCommunitiesQuery } from '@/graphql/queries'
const mockClient = createMockClient()
const apolloProvider = new VueApollo({
@ -61,6 +61,28 @@ describe('TransactionForm', () => {
}),
)
mockClient.setRequestHandler(
selectCommunitiesQuery,
jest.fn().mockResolvedValue({
data: {
communities: [
{
uuid: '8f4c146a-79b5-413f-89ed-53f624ec49b2',
name: 'Gradido Entwicklung',
description: 'Gradido-Community einer lokalen Entwicklungsumgebung.',
foreign: false,
},
{
uuid: 'ashasas',
name: 'Hunde-Community',
description: 'Hier geht es um Hunde',
foreign: true,
},
],
},
}),
)
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
@ -352,6 +374,12 @@ Die ganze Welt bezwingen.“`)
memo: 'Long enough',
selected: 'send',
userName: '',
targetCommunity: {
description: 'Gradido-Community einer lokalen Entwicklungsumgebung.',
foreign: false,
name: 'Gradido Entwicklung',
uuid: '8f4c146a-79b5-413f-89ed-53f624ec49b2',
},
},
],
])

View File

@ -54,7 +54,12 @@
<b-col>{{ $t('form.recipientCommunity') }}</b-col>
</b-row>
<b-row>
<b-col class="font-weight-bold">{{ communityName }}</b-col>
<b-col class="font-weight-bold">
<community-switch
v-model="form.targetCommunity"
:disabled="isBalanceDisabled"
/>
</b-col>
</b-row>
</b-col>
<b-col cols="12" v-if="radioSelected === sendTypes.send">
@ -137,6 +142,7 @@ import { SEND_TYPES } from '@/pages/Send'
import InputIdentifier from '@/components/Inputs/InputIdentifier'
import InputAmount from '@/components/Inputs/InputAmount'
import InputTextarea from '@/components/Inputs/InputTextarea'
import CommunitySwitch from '@/components/CommunitySwitch.vue'
import { user as userQuery } from '@/graphql/queries'
import { isEmpty } from 'lodash'
import { COMMUNITY_NAME } from '@/config'
@ -147,6 +153,7 @@ export default {
InputIdentifier,
InputAmount,
InputTextarea,
CommunitySwitch,
},
props: {
balance: { type: Number, default: 0 },
@ -154,6 +161,12 @@ export default {
amount: { type: Number, default: 0 },
memo: { type: String, default: '' },
selected: { type: String, default: 'send' },
targetCommunity: {
type: Object,
default: function () {
return { uuid: '', name: COMMUNITY_NAME }
},
},
},
data() {
return {
@ -161,10 +174,10 @@ export default {
identifier: this.identifier,
amount: this.amount ? String(this.amount) : '',
memo: this.memo,
targetCommunity: this.targetCommunity,
},
radioSelected: this.selected,
userName: '',
communityName: COMMUNITY_NAME,
}
},
methods: {
@ -179,6 +192,7 @@ export default {
amount: Number(this.form.amount.replace(',', '.')),
memo: this.form.memo,
userName: this.userName,
targetCommunity: this.form.targetCommunity,
})
},
onReset(event) {
@ -186,6 +200,7 @@ export default {
this.form.identifier = ''
this.form.amount = ''
this.form.memo = ''
this.form.targetCommunity = { uuid: '', name: COMMUNITY_NAME }
this.$refs.formValidator.validate()
if (this.$route.query && !isEmpty(this.$route.query))
this.$router.replace({ query: undefined })

View File

@ -71,8 +71,18 @@ export const createUser = gql`
`
export const sendCoins = gql`
mutation($identifier: String!, $amount: Decimal!, $memo: String!) {
sendCoins(identifier: $identifier, amount: $amount, memo: $memo)
mutation(
$recipientCommunityIdentifier: String!
$recipientIdentifier: String!
$amount: Decimal!
$memo: String!
) {
sendCoins(
recipientCommunityIdentifier: $recipientCommunityIdentifier
recipientIdentifier: $recipientIdentifier
amount: $amount
memo: $memo
)
}
`

View File

@ -72,14 +72,13 @@ export const listGDTEntriesQuery = gql`
}
`
export const communities = gql`
export const selectCommunities = gql`
query {
communities {
id
uuid
name
url
description
registerUrl
foreign
}
}
`

View File

@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils'
import Send, { SEND_TYPES } from './Send'
import Send from './Send'
import { toastErrorSpy, toastSuccessSpy } from '@test/testSetup'
import { TRANSACTION_STEPS } from '@/components/GddSend'
import { sendCoins, createTransactionLink } from '@/graphql/mutations.js'
@ -118,11 +118,10 @@ describe('Send', () => {
expect.objectContaining({
mutation: sendCoins,
variables: {
identifier: 'user@example.org',
recipientIdentifier: 'user@example.org',
amount: 23.45,
memo: 'Make the best of it!',
selected: SEND_TYPES.send,
userName: '',
recipientCommunityIdentifier: '',
},
}),
)
@ -217,11 +216,10 @@ describe('Send', () => {
expect.objectContaining({
mutation: sendCoins,
variables: {
identifier: 'gradido-ID',
recipientIdentifier: 'gradido-ID',
amount: 34.56,
memo: 'Make the best of it!',
selected: SEND_TYPES.send,
userName: '',
recipientCommunityIdentifier: '',
},
}),
)

View File

@ -122,7 +122,13 @@ export default {
this.$apollo
.mutate({
mutation: sendCoins,
variables: this.transactionData,
variables: {
// from target community we need only the uuid
recipientCommunityIdentifier: this.transactionData.targetCommunity.uuid,
recipientIdentifier: this.transactionData.identifier,
amount: this.transactionData.amount,
memo: this.transactionData.memo,
},
})
.then(() => {
this.error = false