Merge branch 'master' into 1555-Admin-see-user-generated-link

This commit is contained in:
Alexander Friedland 2022-03-24 19:26:31 +01:00 committed by GitHub
commit af90bb4c3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 167 additions and 33 deletions

View File

@ -1,10 +1,12 @@
import { mount } from '@vue/test-utils'
import TransactionForm from './TransactionForm'
import flushPromises from 'flush-promises'
import { SEND_TYPES } from '@/pages/Send.vue'
import DashboardLayout from '@/layouts/DashboardLayout_gdd.vue'
const localVue = global.localVue
describe('GddSend', () => {
describe('TransactionForm', () => {
let wrapper
const mocks = {
@ -25,7 +27,12 @@ describe('GddSend', () => {
}
const Wrapper = () => {
return mount(TransactionForm, { localVue, mocks, propsData })
return mount(TransactionForm, {
localVue,
mocks,
propsData,
provide: DashboardLayout.provide,
})
}
describe('mount', () => {
@ -34,7 +41,7 @@ describe('GddSend', () => {
})
it('renders the component', () => {
expect(wrapper.find('div.transaction-form').exists()).toBeTruthy()
expect(wrapper.find('div.transaction-form').exists()).toBe(true)
})
describe('transaction form disable because balance 0,0 GDD', () => {
@ -51,7 +58,7 @@ describe('GddSend', () => {
expect(wrapper.find('.text-danger').text()).toBe('form.no_gdd_available')
})
it('has no reset button and no submit button ', () => {
expect(wrapper.find('.test-buttons').exists()).toBeFalsy()
expect(wrapper.find('.test-buttons').exists()).toBe(false)
})
})
@ -63,13 +70,17 @@ describe('GddSend', () => {
await wrapper.findAll('input[type="radio"]').at(0).setChecked()
})
it('has SEND_TYPES = send', () => {
expect(wrapper.vm.selected).toBe(SEND_TYPES.send)
})
describe('transaction form', () => {
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()).toBeFalsy()
expect(wrapper.find('.errors').exists()).toBe(false)
})
it('has a reset button', () => {
expect(wrapper.find('.test-buttons').findAll('button').at(0).attributes('type')).toBe(
@ -159,13 +170,13 @@ describe('GddSend', () => {
it('flushes no errors when amount is valid', async () => {
await wrapper.find('#input-group-2').find('input').setValue('87.34')
await flushPromises()
expect(wrapper.find('span.errors').exists()).toBeFalsy()
expect(wrapper.find('span.errors').exists()).toBe(false)
})
})
describe('message text box', () => {
it('has an textarea field', () => {
expect(wrapper.find('#input-group-3').find('textarea').exists()).toBeTruthy()
expect(wrapper.find('#input-group-3').find('textarea').exists()).toBe(true)
})
it('has an chat-right-text icon', () => {
@ -187,13 +198,13 @@ describe('GddSend', () => {
it('flushes no error message when memo is valid', async () => {
await wrapper.find('#input-group-3').find('textarea').setValue('Long enough')
await flushPromises()
expect(wrapper.find('span.errors').exists()).toBeFalsy()
expect(wrapper.find('span.errors').exists()).toBe(false)
})
})
describe('cancel button', () => {
it('has a cancel button', () => {
expect(wrapper.find('button[type="reset"]').exists()).toBeTruthy()
expect(wrapper.find('button[type="reset"]').exists()).toBe(true)
})
it('has the text "form.cancel"', () => {
@ -242,16 +253,17 @@ describe('GddSend', () => {
})
})
describe('is selected: "link"', () => {
describe('create transaction link', () => {
beforeEach(async () => {
// await wrapper.setData({
// selected: 'link',
// })
await wrapper.findAll('input[type="radio"]').at(1).setChecked()
})
it('has SEND_TYPES = link', () => {
expect(wrapper.vm.selected).toBe(SEND_TYPES.link)
})
it('has no input field of id input-group-1', () => {
expect(wrapper.find('#input-group-1').isVisible()).toBeFalsy()
expect(wrapper.find('#input-group-1').exists()).toBe(false)
})
})
})

View File

@ -16,16 +16,15 @@
</b-form-radio>
</b-col>
</b-row>
<div class="mt-4" v-show="selected === sendTypes.link">
<div class="mt-4" v-if="selected === sendTypes.link">
<h2 class="alert-heading">{{ $t('gdd_per_link.header') }}</h2>
<div>
{{ $t('gdd_per_link.choose-amount') }}
</div>
</div>
<div>
<div v-if="selected === sendTypes.send">
<validation-provider
v-show="selected === sendTypes.send"
name="Email"
:rules="{
required: selected === sendTypes.send ? true : false,
@ -62,9 +61,7 @@
</validation-provider>
</div>
<br />
<div>
<div class="mt-4 mb-4">
<validation-provider
:name="$t('form.amount')"
:rules="{
@ -97,7 +94,7 @@
</validation-provider>
</div>
<div class="mt-4">
<div class="mb-4">
<validation-provider
:rules="{
required: true,
@ -125,7 +122,7 @@
</b-col>
</validation-provider>
</div>
<br />
<div v-if="!!isBalanceDisabled" class="text-danger">
{{ $t('form.no_gdd_available') }}
</div>
@ -141,7 +138,6 @@
</b-button>
</b-col>
</b-row>
<br />
</b-form>
</validation-observer>
@ -164,6 +160,7 @@ export default {
amount: { type: Number, default: 0 },
memo: { type: String, default: '' },
},
inject: ['getTunneledEmail'],
data() {
return {
amountFocused: false,
@ -211,6 +208,12 @@ export default {
sendTypes() {
return SEND_TYPES
},
recipientEmail() {
return this.getTunneledEmail()
},
},
created() {
this.form.email = this.recipientEmail ? this.recipientEmail : ''
},
}
</script>

View File

@ -3,10 +3,6 @@ import GddTransactionList from './GddTransactionList'
const localVue = global.localVue
const errorHandler = jest.fn()
localVue.config.errorHandler = errorHandler
const scrollToMock = jest.fn()
global.scrollTo = scrollToMock

View File

@ -23,6 +23,7 @@
class="list-group-item"
v-bind="transactions[index]"
:decayStartBlock="decayStartBlock"
v-on="$listeners"
/>
</template>
@ -31,6 +32,7 @@
class="list-group-item"
v-bind="transactions[index]"
:decayStartBlock="decayStartBlock"
v-on="$listeners"
/>
</template>
@ -39,6 +41,7 @@
class="list-group-item"
v-bind="transactions[index]"
:decayStartBlock="decayStartBlock"
v-on="$listeners"
/>
</template>

View File

@ -0,0 +1,75 @@
import { mount } from '@vue/test-utils'
import AmountAndNameRow from './AmountAndNameRow'
const localVue = global.localVue
const mocks = {
$router: {
push: jest.fn(),
},
}
const propsData = {
amount: '19.99',
text: 'Some text',
}
describe('AmountAndNameRow', () => {
let wrapper
const Wrapper = () => {
return mount(AmountAndNameRow, { localVue, mocks, propsData })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders the component', () => {
expect(wrapper.find('div.amount-and-name-row').exists()).toBe(true)
})
describe('without linked user', () => {
it('has a span with the text', () => {
expect(wrapper.find('div.gdd-transaction-list-item-name').text()).toBe('Some text')
})
it('has no link', () => {
expect(wrapper.find('div.gdd-transaction-list-item-name').find('a').exists()).toBe(false)
})
})
describe('with linked user', () => {
beforeEach(async () => {
await wrapper.setProps({
linkedUser: { firstName: 'Bibi', lastName: 'Bloxberg', email: 'bibi@bloxberg.de' },
})
})
it('has a link with first and last name', () => {
expect(wrapper.find('div.gdd-transaction-list-item-name').text()).toBe('Bibi Bloxberg')
})
it('has a link', () => {
expect(wrapper.find('div.gdd-transaction-list-item-name').find('a').exists()).toBe(true)
})
describe('click link', () => {
beforeEach(async () => {
await wrapper.find('div.gdd-transaction-list-item-name').find('a').trigger('click')
})
it('emits set tunneled email', () => {
expect(wrapper.emitted('set-tunneled-email')).toEqual([['bibi@bloxberg.de']])
})
it('pushes the route with query for email', () => {
expect(mocks.$router.push).toBeCalledWith({
path: '/send',
})
})
})
})
})
})

View File

@ -10,7 +10,10 @@
</b-col>
<b-col cols="7">
<div class="gdd-transaction-list-item-name">
{{ itemText }}
<b-link v-if="linkedUser && linkedUser.email" @click.stop="tunnelEmail">
{{ itemText }}
</b-link>
<span v-else>{{ itemText }}</span>
</div>
</b-col>
</b-row>
@ -33,6 +36,12 @@ export default {
required: false,
},
},
methods: {
tunnelEmail() {
this.$emit('set-tunneled-email', this.linkedUser.email)
this.$router.push({ path: '/send' })
},
},
computed: {
itemText() {
return this.linkedUser

View File

@ -12,7 +12,7 @@
<b-col cols="11">
<!-- Amount / Name || Text -->
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" />
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" v-on="$listeners" />
<!-- Nachricht Memo -->
<memo-row :memo="memo" />

View File

@ -13,7 +13,7 @@
<b-col cols="11">
<!-- Amount / Name || Text -->
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" />
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" v-on="$listeners" />
<!-- Nachricht Memo -->
<memo-row :memo="memo" />

View File

@ -13,7 +13,7 @@
<b-col cols="11">
<!-- Amount / Name -->
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" />
<amount-and-name-row :amount="amount" :linkedUser="linkedUser" v-on="$listeners" />
<!-- Memo -->
<memo-row :memo="memo" />

View File

@ -67,6 +67,9 @@ export const transactionsQuery = gql`
end
duration
}
linkedUser {
email
}
}
}
}

View File

@ -276,5 +276,14 @@ describe('DashboardLayoutGdd', () => {
})
})
})
describe('set tunneled email', () => {
it('updates tunneled email', async () => {
await wrapper
.findComponent({ ref: 'router-view' })
.vm.$emit('set-tunneled-email', 'bibi@bloxberg.de')
expect(wrapper.vm.tunneledEmail).toBe('bibi@bloxberg.de')
})
})
})
})

View File

@ -28,6 +28,7 @@
:pending="pending"
:decayStartBlock="decayStartBlock"
@update-transactions="updateTransactions"
@set-tunneled-email="setTunneledEmail"
></router-view>
</fade-transition>
</div>
@ -63,6 +64,12 @@ export default {
pending: true,
visible: false,
decayStartBlock: new Date(),
tunneledEmail: null,
}
},
provide() {
return {
getTunneledEmail: () => this.tunneledEmail,
}
},
methods: {
@ -118,6 +125,9 @@ export default {
setVisible(bool) {
this.visible = bool
},
setTunneledEmail(email) {
this.tunneledEmail = email
},
},
computed: {
elopageUri() {

View File

@ -22,6 +22,7 @@
:transaction-count="transactionCount"
:transactionLinkCount="transactionLinkCount"
@update-transactions="updateTransactions"
v-on="$listeners"
/>
<gdd-transaction-list-footer :count="transactionCount" />
</div>

View File

@ -3,6 +3,7 @@ import Send, { SEND_TYPES } from './Send'
import { toastErrorSpy, toastSuccessSpy } from '@test/testSetup'
import { TRANSACTION_STEPS } from '@/components/GddSend.vue'
import { sendCoins, createTransactionLink } from '@/graphql/mutations.js'
import DashboardLayout from '@/layouts/DashboardLayout_gdd.vue'
const apolloMutationMock = jest.fn()
apolloMutationMock.mockResolvedValue('success')
@ -31,10 +32,18 @@ describe('Send', () => {
$apollo: {
mutate: apolloMutationMock,
},
$route: {
query: {},
},
}
const Wrapper = () => {
return mount(Send, { localVue, mocks, propsData })
return mount(Send, {
localVue,
mocks,
propsData,
provide: DashboardLayout.provide,
})
}
describe('mount', () => {
@ -73,9 +82,10 @@ describe('Send', () => {
})
it('restores the previous data in the formular', () => {
expect(wrapper.find('#input-group-1').find('input').vm.$el.value).toBe(
/* expect(wrapper.find('#input-group-1').find('input').vm.$el.value).toBe(
'user@example.org',
)
*/
expect(wrapper.find('#input-group-2').find('input').vm.$el.value).toBe('23.45')
expect(wrapper.find('#input-group-3').find('textarea').vm.$el.value).toBe(
'Make the best of it!',

View File

@ -128,6 +128,7 @@ export default {
})
.then(() => {
this.error = false
this.$emit('set-tunneled-email', null)
this.updateTransactions({})
this.transactionData = { ...EMPTY_TRANSACTION_DATA }
this.currentTransactionStep = TRANSACTION_STEPS.transactionResultSendSuccess
@ -145,6 +146,7 @@ export default {
variables: { amount: this.transactionData.amount, memo: this.transactionData.memo },
})
.then((result) => {
this.$emit('set-tunneled-email', null)
this.code = result.data.createTransactionLink.code
this.currentTransactionStep = TRANSACTION_STEPS.transactionResultLink
this.updateTransactions({})

View File

@ -12,6 +12,7 @@
:show-pagination="true"
:decayStartBlock="decayStartBlock"
@update-transactions="updateTransactions"
v-on="$listeners"
/>
</b-tab>