diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index f643295de..bcdb2f7ec 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -35,6 +35,7 @@ export enum RIGHTS { CREATE_CONTRIBUTION_MESSAGE = 'CREATE_CONTRIBUTION_MESSAGE', LIST_ALL_CONTRIBUTION_MESSAGES = 'LIST_ALL_CONTRIBUTION_MESSAGES', OPEN_CREATIONS = 'OPEN_CREATIONS', + USER = 'USER', // Admin SEARCH_USERS = 'SEARCH_USERS', SET_USER_ROLE = 'SET_USER_ROLE', diff --git a/backend/src/auth/ROLES.ts b/backend/src/auth/ROLES.ts index 2f3b4e081..df1ee0271 100644 --- a/backend/src/auth/ROLES.ts +++ b/backend/src/auth/ROLES.ts @@ -34,6 +34,7 @@ export const ROLE_USER = new Role('user', [ RIGHTS.CREATE_CONTRIBUTION_MESSAGE, RIGHTS.LIST_ALL_CONTRIBUTION_MESSAGES, RIGHTS.OPEN_CREATIONS, + RIGHTS.USER, ]) export const ROLE_ADMIN = new Role('admin', Object.values(RIGHTS)) // all rights diff --git a/backend/src/graphql/arg/TransactionSendArgs.ts b/backend/src/graphql/arg/TransactionSendArgs.ts index d91cecbcd..3f5fa8436 100644 --- a/backend/src/graphql/arg/TransactionSendArgs.ts +++ b/backend/src/graphql/arg/TransactionSendArgs.ts @@ -4,7 +4,7 @@ import { ArgsType, Field } from 'type-graphql' @ArgsType() export default class TransactionSendArgs { @Field(() => String) - email: string + identifier: string @Field(() => Decimal) amount: Decimal diff --git a/backend/src/graphql/resolver/TransactionResolver.test.ts b/backend/src/graphql/resolver/TransactionResolver.test.ts index a2e2e7e75..118ac5d5a 100644 --- a/backend/src/graphql/resolver/TransactionResolver.test.ts +++ b/backend/src/graphql/resolver/TransactionResolver.test.ts @@ -27,8 +27,6 @@ import { garrickOllivander } from '@/seeds/users/garrick-ollivander' import { peterLustig } from '@/seeds/users/peter-lustig' import { stephenHawking } from '@/seeds/users/stephen-hawking' -import { findUserByEmail } from './UserResolver' - let mutate: any, query: any, con: any let testEnv: any @@ -84,7 +82,7 @@ describe('send coins', () => { await mutate({ mutation: sendCoins, variables: { - email: 'wrong@email.com', + identifier: 'wrong@email.com', amount: 100, memo: 'test', }, @@ -112,22 +110,20 @@ describe('send coins', () => { await mutate({ mutation: sendCoins, variables: { - email: 'stephen@hawking.uk', + identifier: 'stephen@hawking.uk', amount: 100, memo: 'test', }, }), ).toEqual( expect.objectContaining({ - errors: [new GraphQLError('The recipient account was deleted')], + errors: [new GraphQLError('No user to given contact')], }), ) }) - it('logs the error thrown', async () => { - // find peter to check the log - const user = await findUserByEmail('stephen@hawking.uk') - expect(logger.error).toBeCalledWith('The recipient account was deleted', user) + it('logs the error thrown', () => { + expect(logger.error).toBeCalledWith('No user to given contact', 'stephen@hawking.uk') }) }) @@ -143,22 +139,23 @@ describe('send coins', () => { await mutate({ mutation: sendCoins, variables: { - email: 'garrick@ollivander.com', + identifier: 'garrick@ollivander.com', amount: 100, memo: 'test', }, }), ).toEqual( expect.objectContaining({ - errors: [new GraphQLError('The recipient account is not activated')], + errors: [new GraphQLError('No user with this credentials')], }), ) }) - it('logs the error thrown', async () => { - // find peter to check the log - const user = await findUserByEmail('garrick@ollivander.com') - expect(logger.error).toBeCalledWith('The recipient account is not activated', user) + it('logs the error thrown', () => { + expect(logger.error).toBeCalledWith( + 'No user with this credentials', + 'garrick@ollivander.com', + ) }) }) }) @@ -178,7 +175,7 @@ describe('send coins', () => { await mutate({ mutation: sendCoins, variables: { - email: 'bob@baumeister.de', + identifier: 'bob@baumeister.de', amount: 100, memo: 'test', }, @@ -202,7 +199,7 @@ describe('send coins', () => { await mutate({ mutation: sendCoins, variables: { - email: 'peter@lustig.de', + identifier: 'peter@lustig.de', amount: 100, memo: 'test', }, @@ -226,7 +223,7 @@ describe('send coins', () => { await mutate({ mutation: sendCoins, variables: { - email: 'peter@lustig.de', + identifier: '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', }, @@ -250,7 +247,7 @@ describe('send coins', () => { await mutate({ mutation: sendCoins, variables: { - email: 'peter@lustig.de', + identifier: 'peter@lustig.de', amount: 100, memo: 'testing', }, @@ -300,7 +297,7 @@ describe('send coins', () => { await mutate({ mutation: sendCoins, variables: { - email: 'peter@lustig.de', + identifier: 'peter@lustig.de', amount: -50, memo: 'testing negative', }, @@ -323,7 +320,7 @@ describe('send coins', () => { await mutate({ mutation: sendCoins, variables: { - email: 'peter@lustig.de', + identifier: 'peter@lustig.de', amount: 50, memo: 'unrepeatable memo', }, @@ -380,7 +377,7 @@ describe('send coins', () => { mutate({ mutation: sendCoins, variables: { - email: 'peter@lustig.de', + identifier: 'peter@lustig.de', amount: 10, memo: 'first transaction', }, @@ -396,7 +393,7 @@ describe('send coins', () => { mutate({ mutation: sendCoins, variables: { - email: 'peter@lustig.de', + identifier: 'peter@lustig.de', amount: 20, memo: 'second transaction', }, @@ -412,7 +409,7 @@ describe('send coins', () => { mutate({ mutation: sendCoins, variables: { - email: 'peter@lustig.de', + identifier: 'peter@lustig.de', amount: 30, memo: 'third transaction', }, @@ -428,7 +425,7 @@ describe('send coins', () => { mutate({ mutation: sendCoins, variables: { - email: 'peter@lustig.de', + identifier: 'peter@lustig.de', amount: 40, memo: 'fourth transaction', }, diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index 430cdb363..4c8ab0061 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -35,7 +35,7 @@ import { virtualLinkTransaction, virtualDecayTransaction } from '@/util/virtualT import { BalanceResolver } from './BalanceResolver' import { MEMO_MAX_CHARS, MEMO_MIN_CHARS } from './const/const' -import { findUserByEmail } from './UserResolver' +import { findUserByIdentifier } from './util/findUserByIdentifier' import { getLastTransaction } from './util/getLastTransaction' export const executeTransaction = async ( @@ -149,7 +149,6 @@ export const executeTransaction = async ( } finally { await queryRunner.release() } - logger.debug(`prepare Email for transaction received...`) await sendTransactionReceivedEmail({ firstName: recipient.firstName, lastName: recipient.lastName, @@ -299,10 +298,10 @@ export class TransactionResolver { @Authorized([RIGHTS.SEND_COINS]) @Mutation(() => Boolean) async sendCoins( - @Args() { email, amount, memo }: TransactionSendArgs, + @Args() { identifier, amount, memo }: TransactionSendArgs, @Ctx() context: Context, ): Promise { - logger.info(`sendCoins(email=${email}, amount=${amount}, memo=${memo})`) + logger.info(`sendCoins(identifier=${identifier}, amount=${amount}, memo=${memo})`) if (amount.lte(0)) { throw new LogError('Amount to send must be positive', amount) } @@ -311,13 +310,9 @@ export class TransactionResolver { const senderUser = getUser(context) // validate recipient user - const recipientUser = await findUserByEmail(email) - if (recipientUser.deletedAt) { - throw new LogError('The recipient account was deleted', recipientUser) - } - const emailContact = recipientUser.emailContact - if (!emailContact.emailChecked) { - throw new LogError('The recipient account is not activated', recipientUser) + const recipientUser = await findUserByIdentifier(identifier) + if (!recipientUser) { + throw new LogError('The recipient user was not found', recipientUser) } await executeTransaction(amount, memo, senderUser, recipientUser) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 69a5f824f..43b62b173 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -11,7 +11,7 @@ import { TransactionLink } from '@entity/TransactionLink' import { User } from '@entity/User' import { UserContact } from '@entity/UserContact' import { GraphQLError } from 'graphql' -import { validate as validateUUID, version as versionUUID } from 'uuid' +import { v4 as uuidv4, validate as validateUUID, version as versionUUID } from 'uuid' import { OptInType } from '@enum/OptInType' import { PasswordEncryptionType } from '@enum/PasswordEncryptionType' @@ -46,7 +46,13 @@ import { unDeleteUser, sendActivationEmail, } from '@/seeds/graphql/mutations' -import { verifyLogin, queryOptIn, searchAdminUsers, searchUsers } from '@/seeds/graphql/queries' +import { + verifyLogin, + queryOptIn, + searchAdminUsers, + searchUsers, + user as userQuery, +} from '@/seeds/graphql/queries' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { bobBaumeister } from '@/seeds/users/bob-baumeister' import { garrickOllivander } from '@/seeds/users/garrick-ollivander' @@ -2298,6 +2304,124 @@ describe('UserResolver', () => { }) }) }) + + describe('user', () => { + beforeEach(() => { + jest.clearAllMocks() + }) + + describe('unauthenticated', () => { + it('throws and logs "401 Unauthorized" error', async () => { + await expect( + query({ + query: userQuery, + variables: { + identifier: 'identifier', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('401 Unauthorized')], + }), + ) + expect(logger.error).toBeCalledWith('401 Unauthorized') + }) + }) + + describe('authenticated', () => { + const uuid = uuidv4() + + beforeAll(async () => { + user = await userFactory(testEnv, bibiBloxberg) + await mutate({ + mutation: login, + variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, + }) + }) + + describe('identifier is no gradido ID and no email', () => { + it('throws and logs "Unknown identifier type" error', async () => { + await expect( + query({ + query: userQuery, + variables: { + identifier: 'identifier', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('Unknown identifier type')], + }), + ) + expect(logger.error).toBeCalledWith('Unknown identifier type', 'identifier') + }) + }) + + describe('identifier is not found', () => { + it('throws and logs "No user found to given identifier" error', async () => { + await expect( + query({ + query: userQuery, + variables: { + identifier: uuid, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('No user found to given identifier')], + }), + ) + expect(logger.error).toBeCalledWith('No user found to given identifier', uuid) + }) + }) + + describe('identifier is found via email', () => { + it('returns user', async () => { + await expect( + query({ + query: userQuery, + variables: { + identifier: 'bibi@bloxberg.de', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + user: { + firstName: 'Bibi', + lastName: 'Bloxberg', + }, + }, + errors: undefined, + }), + ) + }) + }) + + describe('identifier is found via gradidoID', () => { + it('returns user', async () => { + await expect( + query({ + query: userQuery, + variables: { + identifier: user.gradidoID, + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + user: { + firstName: 'Bibi', + lastName: 'Bloxberg', + }, + }, + errors: undefined, + }), + ) + }) + }) + }) + }) }) describe('printTimeDuration', () => { diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index a01719775..17862e820 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -72,6 +72,7 @@ import { getTimeDurationObject, printTimeDuration } from '@/util/time' import { FULL_CREATION_AVAILABLE } from './const/const' import { getUserCreations } from './util/creations' +import { findUserByIdentifier } from './util/findUserByIdentifier' // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-commonjs const random = require('random-bigint') @@ -819,6 +820,12 @@ export class UserResolver { return true } + + @Authorized([RIGHTS.USER]) + @Query(() => User) + async user(@Arg('identifier') identifier: string): Promise { + return new User(await findUserByIdentifier(identifier)) + } } export async function findUserByEmail(email: string): Promise { diff --git a/backend/src/graphql/resolver/semaphore.test.ts b/backend/src/graphql/resolver/semaphore.test.ts index 6963c980e..db411bb62 100644 --- a/backend/src/graphql/resolver/semaphore.test.ts +++ b/backend/src/graphql/resolver/semaphore.test.ts @@ -152,7 +152,7 @@ describe('semaphore', () => { }) const bibisTransaction = mutate({ mutation: sendCoins, - variables: { email: 'bob@baumeister.de', amount: '50', memo: 'Das ist für dich, Bob' }, + variables: { identifier: 'bob@baumeister.de', amount: '50', memo: 'Das ist für dich, Bob' }, }) await mutate({ mutation: login, @@ -168,7 +168,7 @@ describe('semaphore', () => { }) const bobsTransaction = mutate({ mutation: sendCoins, - variables: { email: 'bibi@bloxberg.de', amount: '50', memo: 'Das ist für dich, Bibi' }, + variables: { identifier: 'bibi@bloxberg.de', amount: '50', memo: 'Das ist für dich, Bibi' }, }) await mutate({ mutation: login, diff --git a/backend/src/graphql/resolver/util/findUserByIdentifier.ts b/backend/src/graphql/resolver/util/findUserByIdentifier.ts new file mode 100644 index 000000000..a96fd1451 --- /dev/null +++ b/backend/src/graphql/resolver/util/findUserByIdentifier.ts @@ -0,0 +1,36 @@ +import { User as DbUser } from '@entity/User' +import { UserContact as DbUserContact } from '@entity/UserContact' +import { validate, version } from 'uuid' + +import LogError from '@/server/LogError' + +export const findUserByIdentifier = async (identifier: string): Promise => { + let user: DbUser | undefined + if (validate(identifier) && version(identifier) === 4) { + user = await DbUser.findOne({ where: { gradidoID: identifier }, relations: ['emailContact'] }) + if (!user) { + throw new LogError('No user found to given identifier', identifier) + } + } else if (/^.{2,}@.{2,}\..{2,}$/.exec(identifier)) { + const userContact = await DbUserContact.findOne( + { + email: identifier, + emailChecked: true, + }, + { relations: ['user'] }, + ) + if (!userContact) { + throw new LogError('No user with this credentials', identifier) + } + if (!userContact.user) { + throw new LogError('No user to given contact', identifier) + } + user = userContact.user + user.emailContact = userContact + } else { + // last is alias when implemented + throw new LogError('Unknown identifier type', identifier) + } + + return user +} diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 7e141e5d6..b0716ff74 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -75,8 +75,8 @@ export const sendActivationEmail = gql` ` export const sendCoins = gql` - mutation ($email: String!, $amount: Decimal!, $memo: String!) { - sendCoins(email: $email, amount: $amount, memo: $memo) + mutation ($identifier: String!, $amount: Decimal!, $memo: String!) { + sendCoins(identifier: $identifier, amount: $amount, memo: $memo) } ` diff --git a/backend/src/seeds/graphql/queries.ts b/backend/src/seeds/graphql/queries.ts index 03b71b2de..8da5211a4 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -340,3 +340,12 @@ export const listContributionMessages = gql` } } ` + +export const user = gql` + query ($identifier: String!) { + user(identifier: $identifier) { + firstName + lastName + } + } +` diff --git a/frontend/src/components/GddSend/TransactionConfirmationSend.vue b/frontend/src/components/GddSend/TransactionConfirmationSend.vue index b7c35f089..a9058558c 100644 --- a/frontend/src/components/GddSend/TransactionConfirmationSend.vue +++ b/frontend/src/components/GddSend/TransactionConfirmationSend.vue @@ -5,9 +5,7 @@ -
- {{ email }} -
+
{{ userName ? userName : identifier }}
{{ $t('form.memo') }}
{{ memo }}
@@ -64,9 +62,10 @@ export default { name: 'TransactionConfirmationSend', props: { balance: { type: Number, required: true }, - email: { type: String, required: false, default: '' }, + identifier: { type: String, required: false, default: '' }, amount: { type: Number, required: true }, memo: { type: String, required: true }, + userName: { type: String, default: '' }, }, data() { return { diff --git a/frontend/src/components/GddSend/TransactionForm.spec.js b/frontend/src/components/GddSend/TransactionForm.spec.js index 1594d3d72..41f69960e 100644 --- a/frontend/src/components/GddSend/TransactionForm.spec.js +++ b/frontend/src/components/GddSend/TransactionForm.spec.js @@ -2,9 +2,17 @@ import { mount } from '@vue/test-utils' import TransactionForm from './TransactionForm' import flushPromises from 'flush-promises' import { SEND_TYPES } from '@/pages/Send' -import DashboardLayout from '@/layouts/DashboardLayout' +import { createMockClient } from 'mock-apollo-client' +import VueApollo from 'vue-apollo' +import { user as userQuery } from '@/graphql/queries' + +const mockClient = createMockClient() +const apolloProvider = new VueApollo({ + defaultClient: mockClient, +}) const localVue = global.localVue +localVue.use(VueApollo) describe('TransactionForm', () => { let wrapper @@ -22,6 +30,7 @@ describe('TransactionForm', () => { }, $route: { params: {}, + query: {}, }, } @@ -34,10 +43,24 @@ describe('TransactionForm', () => { localVue, mocks, propsData, - provide: DashboardLayout.provide, + apolloProvider, }) } + const userQueryMock = jest.fn() + + mockClient.setRequestHandler( + userQuery, + userQueryMock.mockRejectedValueOnce({ message: 'Query user name fails!' }).mockResolvedValue({ + data: { + user: { + firstName: 'Bibi', + lastName: 'Bloxberg', + }, + }, + }), + ) + describe('mount', () => { beforeEach(() => { wrapper = Wrapper() @@ -139,7 +162,7 @@ describe('TransactionForm', () => { .setValue(' valid@email.com ') await wrapper.find('div[data-test="input-email"]').find('input').trigger('blur') await flushPromises() - expect(wrapper.vm.form.email).toBe('valid@email.com') + expect(wrapper.vm.form.identifier).toBe('valid@email.com') }) }) @@ -290,12 +313,12 @@ Die ganze Welt bezwingen.“`) .find('textarea') .setValue('Long enough') await flushPromises() - expect(wrapper.vm.form.email).toBe('someone@watches.tv') + expect(wrapper.vm.form.identifier).toBe('someone@watches.tv') expect(wrapper.vm.form.amount).toBe('87.23') expect(wrapper.vm.form.memo).toBe('Long enough') await wrapper.find('button[type="reset"]').trigger('click') await flushPromises() - expect(wrapper.vm.form.email).toBe('') + expect(wrapper.vm.form.identifier).toBe('') expect(wrapper.vm.form.amount).toBe('') expect(wrapper.vm.form.memo).toBe('') }) @@ -321,10 +344,11 @@ Die ganze Welt bezwingen.“`) expect(wrapper.emitted('set-transaction')).toEqual([ [ { - email: 'someone@watches.tv', + identifier: 'someone@watches.tv', amount: 87.23, memo: 'Long enough', selected: 'send', + userName: '', }, ], ]) @@ -346,5 +370,26 @@ Die ganze Welt bezwingen.“`) }) }) }) + + describe('with gradido ID', () => { + beforeEach(async () => { + jest.clearAllMocks() + mocks.$route.query.gradidoID = 'gradido-ID' + wrapper = Wrapper() + await wrapper.vm.$nextTick() + }) + + describe('query for username with success', () => { + it('has no email input field', () => { + expect(wrapper.find('div[data-test="input-email"]').exists()).toBe(false) + }) + + it('queries the username', () => { + expect(userQueryMock).toBeCalledWith({ + identifier: 'gradido-ID', + }) + }) + }) + }) }) }) diff --git a/frontend/src/components/GddSend/TransactionForm.vue b/frontend/src/components/GddSend/TransactionForm.vue index b560e0767..7d2a0aae4 100644 --- a/frontend/src/components/GddSend/TransactionForm.vue +++ b/frontend/src/components/GddSend/TransactionForm.vue @@ -50,16 +50,24 @@ -
+
+
+ + {{ $t('form.recipient') }} + + + {{ userName }} + +
5 && + this.form.identifier.length > 5 && parseInt(this.form.amount) <= parseInt(this.balance) && this.form.memo.length > 5 && this.form.memo.length <= 255 @@ -193,15 +217,12 @@ export default { sendTypes() { return SEND_TYPES }, - recipientEmail() { - return this.getTunneledEmail() + gradidoID() { + return this.$route.query && this.$route.query.gradidoID }, }, - created() { - this.setNewRecipientEmail() - }, mounted() { - if (this.form.email !== '') this.$refs.formValidator.validate() + if (this.form.identifier !== '') this.$refs.formValidator.validate() }, } diff --git a/frontend/src/components/GddTransactionList.vue b/frontend/src/components/GddTransactionList.vue index deed0dedb..63e203f31 100644 --- a/frontend/src/components/GddTransactionList.vue +++ b/frontend/src/components/GddTransactionList.vue @@ -37,7 +37,6 @@ @@ -45,7 +44,6 @@ @@ -53,7 +51,6 @@ diff --git a/frontend/src/components/Template/RightSide/LastTransactions.vue b/frontend/src/components/Template/RightSide/LastTransactions.vue index 54e959436..b08fbf89a 100644 --- a/frontend/src/components/Template/RightSide/LastTransactions.vue +++ b/frontend/src/components/Template/RightSide/LastTransactions.vue @@ -32,11 +32,7 @@
- +
diff --git a/frontend/src/components/TransactionRows/Name.spec.js b/frontend/src/components/TransactionRows/Name.spec.js index 839a698ae..2c370bafc 100644 --- a/frontend/src/components/TransactionRows/Name.spec.js +++ b/frontend/src/components/TransactionRows/Name.spec.js @@ -3,9 +3,11 @@ import Name from './Name' const localVue = global.localVue +const routerPushMock = jest.fn() + const mocks = { $router: { - push: jest.fn(), + push: routerPushMock, history: { current: { fullPath: '/transactions', @@ -47,7 +49,7 @@ describe('Name', () => { describe('with linked user', () => { beforeEach(async () => { await wrapper.setProps({ - linkedUser: { firstName: 'Bibi', lastName: 'Bloxberg', email: 'bibi@bloxberg.de' }, + linkedUser: { firstName: 'Bibi', lastName: 'Bloxberg', gradidoID: 'gradido-ID' }, }) }) @@ -64,13 +66,17 @@ describe('Name', () => { 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 router to send', () => { + expect(routerPushMock).toBeCalledWith({ + path: '/send', + }) }) - it('pushes the route with query for email', () => { - expect(mocks.$router.push).toBeCalledWith({ - path: '/send', + it('pushes query for gradidoID', () => { + expect(routerPushMock).toBeCalledWith({ + query: { + gradidoID: 'gradido-ID', + }, }) }) }) diff --git a/frontend/src/components/TransactionRows/Name.vue b/frontend/src/components/TransactionRows/Name.vue index 4b7f8bc6d..8695645d8 100644 --- a/frontend/src/components/TransactionRows/Name.vue +++ b/frontend/src/components/TransactionRows/Name.vue @@ -1,7 +1,7 @@