diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index ed9528b48..0ff43486c 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -34,6 +34,9 @@ import { virtualLinkTransaction, virtualDecayTransaction } from '@/util/virtualT import Decimal from 'decimal.js-light' import { calculateDecay } from '@/util/decay' +const MEMO_MAX_CHARS = 255 +const MEMO_MIN_CHARS = 5 + export const executeTransaction = async ( amount: Decimal, memo: string, @@ -45,6 +48,14 @@ export const executeTransaction = async ( 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 const receivedCallDate = new Date() const sendBalance = await calculateBalance(sender.id, amount.mul(-1), receivedCallDate) diff --git a/frontend/src/components/GddSend/TransactionForm.spec.js b/frontend/src/components/GddSend/TransactionForm.spec.js index e105e2e1b..db971a2bc 100644 --- a/frontend/src/components/GddSend/TransactionForm.spec.js +++ b/frontend/src/components/GddSend/TransactionForm.spec.js @@ -62,11 +62,8 @@ describe('TransactionForm', () => { }) }) - describe('is selected: "send"', () => { + describe('send GDD', () => { beforeEach(async () => { - // await wrapper.setData({ - // selected: 'send', - // }) await wrapper.findAll('input[type="radio"]').at(0).setChecked() }) @@ -78,15 +75,18 @@ describe('TransactionForm', () => { beforeEach(() => { wrapper.setProps({ balance: 100.0 }) }) + describe('transaction form show because balance 100,0 GDD', () => { it('has no warning message ', () => { expect(wrapper.find('.errors').exists()).toBe(false) }) + it('has a reset button', () => { expect(wrapper.find('.test-buttons').findAll('button').at(0).attributes('type')).toBe( 'reset', ) }) + it('has a submit button', () => { expect(wrapper.find('.test-buttons').findAll('button').at(1).attributes('type')).toBe( 'submit', @@ -121,6 +121,12 @@ describe('TransactionForm', () => { 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 () => { await wrapper.find('#input-group-1').find('input').setValue(' valid@email.com ') 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') }) + 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 () => { await wrapper.find('#input-group-3').find('textarea').setValue('Long enough') await flushPromises() diff --git a/frontend/src/components/GddSend/TransactionForm.vue b/frontend/src/components/GddSend/TransactionForm.vue index 4ffc0d3fc..5e683d132 100644 --- a/frontend/src/components/GddSend/TransactionForm.vue +++ b/frontend/src/components/GddSend/TransactionForm.vue @@ -99,7 +99,7 @@ :rules="{ required: true, min: 5, - max: 150, + max: 255, }" :name="$t('form.message')" v-slot="{ errors }"