mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into 1555-Admin-see-user-generated-link
This commit is contained in:
commit
d5b57dcf1c
@ -34,6 +34,9 @@ import { virtualLinkTransaction, virtualDecayTransaction } from '@/util/virtualT
|
|||||||
import Decimal from 'decimal.js-light'
|
import Decimal from 'decimal.js-light'
|
||||||
import { calculateDecay } from '@/util/decay'
|
import { calculateDecay } from '@/util/decay'
|
||||||
|
|
||||||
|
const MEMO_MAX_CHARS = 255
|
||||||
|
const MEMO_MIN_CHARS = 5
|
||||||
|
|
||||||
export const executeTransaction = async (
|
export const executeTransaction = async (
|
||||||
amount: Decimal,
|
amount: Decimal,
|
||||||
memo: string,
|
memo: string,
|
||||||
@ -45,6 +48,14 @@ export const executeTransaction = async (
|
|||||||
throw new Error('Sender and Recipient are the same.')
|
throw new Error('Sender and Recipient are the same.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (memo.length > MEMO_MAX_CHARS) {
|
||||||
|
throw new Error(`memo text is too long (${MEMO_MAX_CHARS} characters maximum)`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memo.length < MEMO_MIN_CHARS) {
|
||||||
|
throw new Error(`memo text is too short (${MEMO_MIN_CHARS} characters minimum)`)
|
||||||
|
}
|
||||||
|
|
||||||
// validate amount
|
// validate amount
|
||||||
const receivedCallDate = new Date()
|
const receivedCallDate = new Date()
|
||||||
const sendBalance = await calculateBalance(sender.id, amount.mul(-1), receivedCallDate)
|
const sendBalance = await calculateBalance(sender.id, amount.mul(-1), receivedCallDate)
|
||||||
|
|||||||
@ -62,11 +62,8 @@ describe('TransactionForm', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('is selected: "send"', () => {
|
describe('send GDD', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
// await wrapper.setData({
|
|
||||||
// selected: 'send',
|
|
||||||
// })
|
|
||||||
await wrapper.findAll('input[type="radio"]').at(0).setChecked()
|
await wrapper.findAll('input[type="radio"]').at(0).setChecked()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -78,15 +75,18 @@ describe('TransactionForm', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper.setProps({ balance: 100.0 })
|
wrapper.setProps({ balance: 100.0 })
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('transaction form show because balance 100,0 GDD', () => {
|
describe('transaction form show because balance 100,0 GDD', () => {
|
||||||
it('has no warning message ', () => {
|
it('has no warning message ', () => {
|
||||||
expect(wrapper.find('.errors').exists()).toBe(false)
|
expect(wrapper.find('.errors').exists()).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('has a reset button', () => {
|
it('has a reset button', () => {
|
||||||
expect(wrapper.find('.test-buttons').findAll('button').at(0).attributes('type')).toBe(
|
expect(wrapper.find('.test-buttons').findAll('button').at(0).attributes('type')).toBe(
|
||||||
'reset',
|
'reset',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('has a submit button', () => {
|
it('has a submit button', () => {
|
||||||
expect(wrapper.find('.test-buttons').findAll('button').at(1).attributes('type')).toBe(
|
expect(wrapper.find('.test-buttons').findAll('button').at(1).attributes('type')).toBe(
|
||||||
'submit',
|
'submit',
|
||||||
@ -121,6 +121,12 @@ describe('TransactionForm', () => {
|
|||||||
expect(wrapper.find('span.errors').text()).toBe('validations.messages.email')
|
expect(wrapper.find('span.errors').text()).toBe('validations.messages.email')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('flushes an error message when email is the email of logged in user', async () => {
|
||||||
|
await wrapper.find('#input-group-1').find('input').setValue('user@example.org')
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.find('span.errors').text()).toBe('form.validation.is-not')
|
||||||
|
})
|
||||||
|
|
||||||
it('trims the email after blur', async () => {
|
it('trims the email after blur', async () => {
|
||||||
await wrapper.find('#input-group-1').find('input').setValue(' valid@email.com ')
|
await wrapper.find('#input-group-1').find('input').setValue(' valid@email.com ')
|
||||||
await wrapper.find('#input-group-1').find('input').trigger('blur')
|
await wrapper.find('#input-group-1').find('input').trigger('blur')
|
||||||
@ -195,6 +201,41 @@ describe('TransactionForm', () => {
|
|||||||
expect(wrapper.find('span.errors').text()).toBe('validations.messages.min')
|
expect(wrapper.find('span.errors').text()).toBe('validations.messages.min')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('flushes an error message when memo is more than 255 characters', async () => {
|
||||||
|
await wrapper.find('#input-group-3').find('textarea').setValue(`
|
||||||
|
Es ist ein König in Thule, der trinkt
|
||||||
|
Champagner, es geht ihm nichts drüber;
|
||||||
|
Und wenn er seinen Champagner trinkt,
|
||||||
|
Dann gehen die Augen ihm über.
|
||||||
|
|
||||||
|
Die Ritter sitzen um ihn her,
|
||||||
|
Die ganze Historische Schule;
|
||||||
|
Ihm aber wird die Zunge schwer,
|
||||||
|
Es lallt der König von Thule:
|
||||||
|
|
||||||
|
„Als Alexander, der Griechenheld,
|
||||||
|
Mit seinem kleinen Haufen
|
||||||
|
Erobert hatte die ganze Welt,
|
||||||
|
Da gab er sich ans Saufen.
|
||||||
|
|
||||||
|
Ihn hatten so durstig gemacht der Krieg
|
||||||
|
Und die Schlachten, die er geschlagen;
|
||||||
|
Er soff sich zu Tode nach dem Sieg,
|
||||||
|
Er konnte nicht viel vertragen.
|
||||||
|
|
||||||
|
Ich aber bin ein stärkerer Mann
|
||||||
|
Und habe mich klüger besonnen:
|
||||||
|
Wie jener endete, fang ich an,
|
||||||
|
Ich hab mit dem Trinken begonnen.
|
||||||
|
|
||||||
|
Im Rausche wird der Heldenzug
|
||||||
|
Mir später weit besser gelingen;
|
||||||
|
Dann werde ich, taumelnd von Krug zu Krug,
|
||||||
|
Die ganze Welt bezwingen.“`)
|
||||||
|
await flushPromises()
|
||||||
|
expect(wrapper.find('span.errors').text()).toBe('validations.messages.max')
|
||||||
|
})
|
||||||
|
|
||||||
it('flushes no error message when memo is valid', async () => {
|
it('flushes no error message when memo is valid', async () => {
|
||||||
await wrapper.find('#input-group-3').find('textarea').setValue('Long enough')
|
await wrapper.find('#input-group-3').find('textarea').setValue('Long enough')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
|
|||||||
@ -99,7 +99,7 @@
|
|||||||
:rules="{
|
:rules="{
|
||||||
required: true,
|
required: true,
|
||||||
min: 5,
|
min: 5,
|
||||||
max: 150,
|
max: 255,
|
||||||
}"
|
}"
|
||||||
:name="$t('form.message')"
|
:name="$t('form.message')"
|
||||||
v-slot="{ errors }"
|
v-slot="{ errors }"
|
||||||
|
|||||||
@ -10,9 +10,20 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
<b-col cols="7">
|
<b-col cols="7">
|
||||||
<div class="gdd-transaction-list-item-name">
|
<div class="gdd-transaction-list-item-name">
|
||||||
<b-link v-if="linkedUser && linkedUser.email" @click.stop="tunnelEmail">
|
<div v-if="linkedUser && linkedUser.email">
|
||||||
{{ itemText }}
|
<b-link @click.stop="tunnelEmail">
|
||||||
</b-link>
|
{{ itemText }}
|
||||||
|
</b-link>
|
||||||
|
<span v-if="transactionLinkId">
|
||||||
|
{{ $t('via_link') }}
|
||||||
|
<b-icon
|
||||||
|
icon="link45deg"
|
||||||
|
variant="muted"
|
||||||
|
class="m-mb-1"
|
||||||
|
:title="$t('gdd_per_link.redeemed-title')"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<span v-else>{{ itemText }}</span>
|
<span v-else>{{ itemText }}</span>
|
||||||
</div>
|
</div>
|
||||||
</b-col>
|
</b-col>
|
||||||
@ -35,6 +46,11 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
transactionLinkId: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
tunnelEmail() {
|
tunnelEmail() {
|
||||||
|
|||||||
@ -13,7 +13,12 @@
|
|||||||
|
|
||||||
<b-col cols="11">
|
<b-col cols="11">
|
||||||
<!-- Amount / Name || Text -->
|
<!-- Amount / Name || Text -->
|
||||||
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" v-on="$listeners" />
|
<amount-and-name-row
|
||||||
|
v-on="$listeners"
|
||||||
|
:amount="amount"
|
||||||
|
:linkedUser="linkedUser"
|
||||||
|
:transactionLinkId="transactionLinkId"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Nachricht Memo -->
|
<!-- Nachricht Memo -->
|
||||||
<memo-row :memo="memo" />
|
<memo-row :memo="memo" />
|
||||||
@ -86,6 +91,10 @@ export default {
|
|||||||
type: Date,
|
type: Date,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
transactionLinkId: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -13,7 +13,12 @@
|
|||||||
|
|
||||||
<b-col cols="11">
|
<b-col cols="11">
|
||||||
<!-- Amount / Name -->
|
<!-- Amount / Name -->
|
||||||
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" v-on="$listeners" />
|
<amount-and-name-row
|
||||||
|
v-on="$listeners"
|
||||||
|
:amount="amount"
|
||||||
|
:linkedUser="linkedUser"
|
||||||
|
:transactionLinkId="transactionLinkId"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Memo -->
|
<!-- Memo -->
|
||||||
<memo-row :memo="memo" />
|
<memo-row :memo="memo" />
|
||||||
@ -87,6 +92,10 @@ export default {
|
|||||||
type: Date,
|
type: Date,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
transactionLinkId: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -70,6 +70,7 @@ export const transactionsQuery = gql`
|
|||||||
linkedUser {
|
linkedUser {
|
||||||
email
|
email
|
||||||
}
|
}
|
||||||
|
transactionLinkId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,6 +115,7 @@
|
|||||||
"redeem-text": "Willst du den Betrag jetzt einlösen?",
|
"redeem-text": "Willst du den Betrag jetzt einlösen?",
|
||||||
"redeemed": "Erfolgreich eingelöst! Deinem Konto wurden {n} GDD gutgeschrieben.",
|
"redeemed": "Erfolgreich eingelöst! Deinem Konto wurden {n} GDD gutgeschrieben.",
|
||||||
"redeemed-at": "Der Link wurde bereits am {date} eingelöst.",
|
"redeemed-at": "Der Link wurde bereits am {date} eingelöst.",
|
||||||
|
"redeemed-title": "eingelöst",
|
||||||
"to-login": "Log dich ein",
|
"to-login": "Log dich ein",
|
||||||
"to-register": "Registriere ein neues Konto",
|
"to-register": "Registriere ein neues Konto",
|
||||||
"valid_until": "Gültig bis"
|
"valid_until": "Gültig bis"
|
||||||
@ -249,5 +250,6 @@
|
|||||||
},
|
},
|
||||||
"transaction-link": {
|
"transaction-link": {
|
||||||
"send_you": "sendet dir"
|
"send_you": "sendet dir"
|
||||||
}
|
},
|
||||||
|
"via_link": "über einen Link"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,6 +115,7 @@
|
|||||||
"redeem-text": "Do you want to redeem the amount now?",
|
"redeem-text": "Do you want to redeem the amount now?",
|
||||||
"redeemed": "Successfully redeemed! Your account has been credited with {n} GDD.",
|
"redeemed": "Successfully redeemed! Your account has been credited with {n} GDD.",
|
||||||
"redeemed-at": "The link was already redeemed on {date}.",
|
"redeemed-at": "The link was already redeemed on {date}.",
|
||||||
|
"redeemed-title": "redeemed",
|
||||||
"to-login": "Log in",
|
"to-login": "Log in",
|
||||||
"to-register": "Register a new account",
|
"to-register": "Register a new account",
|
||||||
"valid_until": "Valid until"
|
"valid_until": "Valid until"
|
||||||
@ -249,5 +250,6 @@
|
|||||||
},
|
},
|
||||||
"transaction-link": {
|
"transaction-link": {
|
||||||
"send_you": "wants to send you"
|
"send_you": "wants to send you"
|
||||||
}
|
},
|
||||||
|
"via_link": "via Link"
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user