From 6c88713f3430e9a406c478fe9738d3793533a8d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 20 Sep 2022 16:20:52 +0200 Subject: [PATCH 01/57] start inserting logger.addContext for userid --- backend/src/graphql/resolver/UserResolver.ts | 6 +++++- backend/src/server/createServer.ts | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index f2fd048fc..e642117df 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -277,6 +277,8 @@ export class UserResolver { logger.error(`User with email=${email} does not exist`) throw new Error('No user with this credentials') }) + logger.addContext('user', dbUser.id) + logger.info(`validation of user still ongoing...`) if (dbUser.deletedAt) { logger.error('The User was permanently deleted in database.') throw new Error('This user was permanently deleted. Contact support for questions.') @@ -303,7 +305,7 @@ export class UserResolver { } // add pubKey in logger-context for layout-pattern X{user} to print it in each logging message logger.addContext('user', dbUser.id) - logger.debug('login credentials valid...') + logger.debug('validation of login credentials successful...') const user = new User(dbUser, await getUserCreation(dbUser.id)) logger.debug('user=' + user) @@ -348,6 +350,7 @@ export class UserResolver { @Args() { email, firstName, lastName, language, publisherId, redeemCode = null }: CreateUserArgs, ): Promise { + logger.addContext('user', 'unknown') logger.info( `createUser(email=${email}, firstName=${firstName}, lastName=${lastName}, language=${language}, publisherId=${publisherId}, redeemCode =${redeemCode})`, ) @@ -483,6 +486,7 @@ export class UserResolver { } await queryRunner.commitTransaction() + logger.addContext('user', dbUser.id) } catch (e) { logger.error(`error during create user with ${e}`) await queryRunner.rollbackTransaction() diff --git a/backend/src/server/createServer.ts b/backend/src/server/createServer.ts index a0b294281..62ea93bf0 100644 --- a/backend/src/server/createServer.ts +++ b/backend/src/server/createServer.ts @@ -35,6 +35,7 @@ const createServer = async ( context: any = serverContext, logger: Logger = apolloLogger, ): Promise => { + logger.addContext('user', 'unknown') logger.debug('createServer...') // open mysql connection From 542b069aa90b5b54cc237b8d906118350694651c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Wed, 21 Sep 2022 04:12:48 +0200 Subject: [PATCH 02/57] reconfig now with rollover feature and userid in logevent-message --- backend/log4js-config.json | 57 +++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/backend/log4js-config.json b/backend/log4js-config.json index 848a4fa79..a096713ec 100644 --- a/backend/log4js-config.json +++ b/backend/log4js-config.json @@ -5,41 +5,66 @@ { "type": "dateFile", "filename": "../logs/backend/access.log", - "pattern": "%d{ISO8601} %p %c %X{user} %f:%l %m", + "pattern": "yyyy-MM-dd", + "layout": + { + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + }, "keepFileExt" : true, - "fileNameSep" : "_" + "fileNameSep" : "_", + "numBackups" : 30 }, "apollo": { "type": "dateFile", "filename": "../logs/backend/apollo.log", - "pattern": "%d{ISO8601} %p %c %m", + "pattern": "yyyy-MM-dd", + "layout": + { + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + }, "keepFileExt" : true, - "fileNameSep" : "_" + "fileNameSep" : "_", + "numBackups" : 30 }, "backend": { "type": "dateFile", "filename": "../logs/backend/backend.log", - "pattern": "%d{ISO8601} %p %c %X{user} %f:%l %m", + "pattern": "yyyy-MM-dd", + "layout": + { + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + }, "keepFileExt" : true, - "fileNameSep" : "_" + "fileNameSep" : "_", + "numBackups" : 30 }, "klicktipp": { "type": "dateFile", "filename": "../logs/backend/klicktipp.log", - "pattern": "%d{ISO8601} %p %c %X{user} %f:%l %m", + "pattern": "yyyy-MM-dd", + "layout": + { + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + }, "keepFileExt" : true, - "fileNameSep" : "_" + "fileNameSep" : "_", + "numBackups" : 30 }, "errorFile": { "type": "dateFile", "filename": "../logs/backend/errors.log", - "pattern": "%d{ISO8601} %p %c %X{user} %f:%l %m", + "pattern": "yyyy-MM-dd", + "layout": + { + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + }, "keepFileExt" : true, - "fileNameSep" : "_" + "fileNameSep" : "_", + "numBackups" : 30 }, "errors": { @@ -52,7 +77,7 @@ "type": "stdout", "layout": { - "type": "pattern", "pattern": "%d{ISO8601} %p %c %X{user} %f:%l %m" + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" } }, "apolloOut": @@ -60,7 +85,7 @@ "type": "stdout", "layout": { - "type": "pattern", "pattern": "%d{ISO8601} %p %c %m" + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" } } }, @@ -74,7 +99,7 @@ "errors" ], "level": "debug", - "enableCallStack": true + "enableCallStack": false }, "apollo": { @@ -85,7 +110,7 @@ "errors" ], "level": "debug", - "enableCallStack": true + "enableCallStack": false }, "backend": { @@ -96,7 +121,7 @@ "errors" ], "level": "debug", - "enableCallStack": true + "enableCallStack": false }, "klicktipp": { @@ -107,7 +132,7 @@ "errors" ], "level": "debug", - "enableCallStack": true + "enableCallStack": false }, "http": { From e844bcc925080239ecb445ff048d509760ec6cff Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 22 Sep 2022 11:47:28 +0200 Subject: [PATCH 03/57] Change login from Query to Mutation. --- backend/src/graphql/resolver/UserResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index f2fd048fc..5b4ad6cdc 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -265,7 +265,7 @@ export class UserResolver { } @Authorized([RIGHTS.LOGIN]) - @Query(() => User) + @Mutation(() => User) @UseMiddleware(klicktippNewsletterStateMiddleware) async login( @Args() { email, password, publisherId }: UnsecureLoginArgs, From f63bfa871a3497c861cb49f3592610a80943d9be Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 22 Sep 2022 11:47:48 +0200 Subject: [PATCH 04/57] Change login call from query to mutation. --- frontend/src/graphql/mutations.js | 18 ++++++++++++++++++ frontend/src/graphql/queries.js | 18 ------------------ frontend/src/pages/Login.vue | 7 +++---- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index 9846784d5..2a2eb6353 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -136,3 +136,21 @@ export const createContributionMessage = gql` } } ` + +export const login = gql` + mutation($email: String!, $password: String!, $publisherId: Int) { + login(email: $email, password: $password, publisherId: $publisherId) { + email + firstName + lastName + language + klickTipp { + newsletterState + } + hasElopage + publisherId + isAdmin + creation + } + } +` diff --git a/frontend/src/graphql/queries.js b/frontend/src/graphql/queries.js index 07b016d0a..a0964aef4 100644 --- a/frontend/src/graphql/queries.js +++ b/frontend/src/graphql/queries.js @@ -1,23 +1,5 @@ import gql from 'graphql-tag' -export const login = gql` - query($email: String!, $password: String!, $publisherId: Int) { - login(email: $email, password: $password, publisherId: $publisherId) { - email - firstName - lastName - language - klickTipp { - newsletterState - } - hasElopage - publisherId - isAdmin - creation - } - } -` - export const verifyLogin = gql` query { verifyLogin { diff --git a/frontend/src/pages/Login.vue b/frontend/src/pages/Login.vue index 6a3db4e39..0b602f74b 100755 --- a/frontend/src/pages/Login.vue +++ b/frontend/src/pages/Login.vue @@ -43,7 +43,7 @@ import InputPassword from '@/components/Inputs/InputPassword' import InputEmail from '@/components/Inputs/InputEmail' import Message from '@/components/Message/Message' -import { login } from '@/graphql/queries' +import { login } from '@/graphql/mutations' export default { name: 'Login', @@ -71,14 +71,13 @@ export default { container: this.$refs.submitButton, }) this.$apollo - .query({ - query: login, + .mutate({ + mutation: login, variables: { email: this.form.email, password: this.form.password, publisherId: this.$store.state.publisherId, }, - fetchPolicy: 'network-only', }) .then(async (result) => { const { From 2d4f88ce844c549f7393e25038bc8d0a01c7f161 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 22 Sep 2022 11:53:54 +0200 Subject: [PATCH 05/57] Refactor logout method from query to mutation. --- backend/src/graphql/resolver/UserResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 5b4ad6cdc..89d524057 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -329,7 +329,7 @@ export class UserResolver { } @Authorized([RIGHTS.LOGOUT]) - @Query(() => String) + @Mutation(() => String) async logout(): Promise { // TODO: We dont need this anymore, but might need this in the future in oder to invalidate a valid JWT-Token. // Furthermore this hook can be useful for tracking user behaviour (did he logout or not? Warn him if he didn't on next login) From 4fdc492a6ca58326673082922ed118c61e9eccd4 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 22 Sep 2022 11:54:36 +0200 Subject: [PATCH 06/57] Change query logout to mutation, call of mutation instead of query. --- frontend/src/graphql/mutations.js | 6 ++++++ frontend/src/graphql/queries.js | 6 ------ frontend/src/layouts/DashboardLayout.vue | 8 +++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index 2a2eb6353..3156c2861 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -154,3 +154,9 @@ export const login = gql` } } ` + +export const logout = gql` + mutation { + logout + } +` diff --git a/frontend/src/graphql/queries.js b/frontend/src/graphql/queries.js index a0964aef4..f772aa931 100644 --- a/frontend/src/graphql/queries.js +++ b/frontend/src/graphql/queries.js @@ -18,12 +18,6 @@ export const verifyLogin = gql` } ` -export const logout = gql` - query { - logout - } -` - export const transactionsQuery = gql` query($currentPage: Int = 1, $pageSize: Int = 25, $order: Order = DESC) { transactionList(currentPage: $currentPage, pageSize: $pageSize, order: $order) { diff --git a/frontend/src/layouts/DashboardLayout.vue b/frontend/src/layouts/DashboardLayout.vue index 8e778ab01..bf33daa83 100755 --- a/frontend/src/layouts/DashboardLayout.vue +++ b/frontend/src/layouts/DashboardLayout.vue @@ -41,7 +41,8 @@ import Navbar from '@/components/Menu/Navbar.vue' import Sidebar from '@/components/Menu/Sidebar.vue' import SessionLogoutTimeout from '@/components/SessionLogoutTimeout.vue' -import { logout, transactionsQuery } from '@/graphql/queries' +import { transactionsQuery } from '@/graphql/queries' +import { logout } from '@/graphql/mutations' import ContentFooter from '@/components/ContentFooter.vue' import { FadeTransition } from 'vue2-transitions' import CONFIG from '@/config' @@ -75,14 +76,15 @@ export default { methods: { async logout() { this.$apollo - .query({ - query: logout, + .mutate({ + mutation: logout, }) .then(() => { this.$store.dispatch('logout') this.$router.push('/login') }) .catch(() => { + console.log('TESTTEST') this.$store.dispatch('logout') if (this.$router.currentRoute.path !== '/login') this.$router.push('/login') }) From 4461ff92a5d6c5d337003ecb4d751518c187bdab Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 22 Sep 2022 12:22:56 +0200 Subject: [PATCH 07/57] Correct tests after changing login and logout from queries to mutations. --- .../graphql/resolver/AdminResolver.test.ts | 58 +++++++++---------- .../ContributionMessageResolver.test.ts | 31 +++++----- .../resolver/ContributionResolver.test.ts | 43 +++++++------- .../src/graphql/resolver/UserResolver.test.ts | 41 +++++++------ backend/src/seeds/factory/contributionLink.ts | 7 +-- backend/src/seeds/factory/creation.ts | 7 +-- backend/src/seeds/factory/transactionLink.ts | 10 ++-- backend/src/seeds/graphql/mutations.ts | 24 ++++++++ backend/src/seeds/graphql/queries.ts | 24 -------- 9 files changed, 127 insertions(+), 118 deletions(-) diff --git a/backend/src/graphql/resolver/AdminResolver.test.ts b/backend/src/graphql/resolver/AdminResolver.test.ts index 75c672bd5..8b91f3fd9 100644 --- a/backend/src/graphql/resolver/AdminResolver.test.ts +++ b/backend/src/graphql/resolver/AdminResolver.test.ts @@ -13,6 +13,7 @@ import { peterLustig } from '@/seeds/users/peter-lustig' import { stephenHawking } from '@/seeds/users/stephen-hawking' import { garrickOllivander } from '@/seeds/users/garrick-ollivander' import { + login, setUserRole, deleteUser, unDeleteUser, @@ -27,7 +28,6 @@ import { } from '@/seeds/graphql/mutations' import { listUnconfirmedContributions, - login, searchUsers, listTransactionLinksAdmin, listContributionLinks, @@ -96,8 +96,8 @@ describe('AdminResolver', () => { describe('without admin rights', () => { beforeAll(async () => { user = await userFactory(testEnv, bibiBloxberg) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) @@ -121,8 +121,8 @@ describe('AdminResolver', () => { describe('with admin rights', () => { beforeAll(async () => { admin = await userFactory(testEnv, peterLustig) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) }) @@ -249,8 +249,8 @@ describe('AdminResolver', () => { describe('without admin rights', () => { beforeAll(async () => { user = await userFactory(testEnv, bibiBloxberg) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) @@ -274,8 +274,8 @@ describe('AdminResolver', () => { describe('with admin rights', () => { beforeAll(async () => { admin = await userFactory(testEnv, peterLustig) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) }) @@ -357,8 +357,8 @@ describe('AdminResolver', () => { describe('without admin rights', () => { beforeAll(async () => { user = await userFactory(testEnv, bibiBloxberg) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) @@ -382,8 +382,8 @@ describe('AdminResolver', () => { describe('with admin rights', () => { beforeAll(async () => { admin = await userFactory(testEnv, peterLustig) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) }) @@ -469,8 +469,8 @@ describe('AdminResolver', () => { describe('without admin rights', () => { beforeAll(async () => { user = await userFactory(testEnv, bibiBloxberg) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) @@ -514,8 +514,8 @@ describe('AdminResolver', () => { beforeAll(async () => { admin = await userFactory(testEnv, peterLustig) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) @@ -766,8 +766,8 @@ describe('AdminResolver', () => { describe('without admin rights', () => { beforeAll(async () => { user = await userFactory(testEnv, bibiBloxberg) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) @@ -875,8 +875,8 @@ describe('AdminResolver', () => { describe('with admin rights', () => { beforeAll(async () => { admin = await userFactory(testEnv, peterLustig) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) }) @@ -1553,8 +1553,8 @@ describe('AdminResolver', () => { describe('without admin rights', () => { beforeAll(async () => { user = await userFactory(testEnv, bibiBloxberg) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) @@ -1599,8 +1599,8 @@ describe('AdminResolver', () => { } // admin: only now log in - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) }) @@ -1859,8 +1859,8 @@ describe('AdminResolver', () => { describe('without admin rights', () => { beforeAll(async () => { user = await userFactory(testEnv, bibiBloxberg) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) @@ -1933,8 +1933,8 @@ describe('AdminResolver', () => { describe('with admin rights', () => { beforeAll(async () => { user = await userFactory(testEnv, peterLustig) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) }) diff --git a/backend/src/graphql/resolver/ContributionMessageResolver.test.ts b/backend/src/graphql/resolver/ContributionMessageResolver.test.ts index 40e9e2ace..bc85c9d58 100644 --- a/backend/src/graphql/resolver/ContributionMessageResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionMessageResolver.test.ts @@ -7,8 +7,9 @@ import { adminCreateContributionMessage, createContribution, createContributionMessage, + login, } from '@/seeds/graphql/mutations' -import { listContributionMessages, login } from '@/seeds/graphql/queries' +import { listContributionMessages } from '@/seeds/graphql/queries' import { userFactory } from '@/seeds/factory/user' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { peterLustig } from '@/seeds/users/peter-lustig' @@ -59,8 +60,8 @@ describe('ContributionMessageResolver', () => { beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) await userFactory(testEnv, peterLustig) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) result = await mutate({ @@ -71,8 +72,8 @@ describe('ContributionMessageResolver', () => { creationDate: new Date().toString(), }, }) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) }) @@ -103,8 +104,8 @@ describe('ContributionMessageResolver', () => { }) it('throws error when contribution.userId equals user.id', async () => { - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) const result2 = await mutate({ @@ -195,8 +196,8 @@ describe('ContributionMessageResolver', () => { describe('authenticated', () => { beforeAll(async () => { - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) @@ -227,8 +228,8 @@ describe('ContributionMessageResolver', () => { }) it('throws error when other user tries to send createContributionMessage', async () => { - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) await expect( @@ -253,8 +254,8 @@ describe('ContributionMessageResolver', () => { describe('valid input', () => { beforeAll(async () => { - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) @@ -304,8 +305,8 @@ describe('ContributionMessageResolver', () => { describe('authenticated', () => { beforeAll(async () => { - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) diff --git a/backend/src/graphql/resolver/ContributionResolver.test.ts b/backend/src/graphql/resolver/ContributionResolver.test.ts index 20f11ff9a..92546e004 100644 --- a/backend/src/graphql/resolver/ContributionResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionResolver.test.ts @@ -8,8 +8,9 @@ import { createContribution, deleteContribution, updateContribution, + login, } from '@/seeds/graphql/mutations' -import { listAllContributions, listContributions, login } from '@/seeds/graphql/queries' +import { listAllContributions, listContributions } from '@/seeds/graphql/queries' import { cleanDB, resetToken, testEnvironment } from '@test/helpers' import { GraphQLError } from 'graphql' import { userFactory } from '@/seeds/factory/user' @@ -54,8 +55,8 @@ describe('ContributionResolver', () => { describe('authenticated with valid user', () => { beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) @@ -197,8 +198,8 @@ describe('ContributionResolver', () => { const bibisCreation = creations.find((creation) => creation.email === 'bibi@bloxberg.de') // eslint-disable-next-line @typescript-eslint/no-non-null-assertion await creationFactory(testEnv, bibisCreation!) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) await mutate({ @@ -310,8 +311,8 @@ describe('ContributionResolver', () => { beforeAll(async () => { await userFactory(testEnv, peterLustig) await userFactory(testEnv, bibiBloxberg) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) result = await mutate({ @@ -393,8 +394,8 @@ describe('ContributionResolver', () => { describe('wrong user tries to update the contribution', () => { beforeAll(async () => { - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) }) @@ -445,8 +446,8 @@ describe('ContributionResolver', () => { describe('update too much so that the limit is exceeded', () => { beforeAll(async () => { - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) }) @@ -553,8 +554,8 @@ describe('ContributionResolver', () => { const bibisCreation = creations.find((creation) => creation.email === 'bibi@bloxberg.de') // eslint-disable-next-line @typescript-eslint/no-non-null-assertion await creationFactory(testEnv, bibisCreation!) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) await mutate({ @@ -630,8 +631,8 @@ describe('ContributionResolver', () => { beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) await userFactory(testEnv, peterLustig) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) result = await mutate({ @@ -668,8 +669,8 @@ describe('ContributionResolver', () => { describe('other user sends a deleteContribtuion', () => { it('returns an error', async () => { - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) await expect( @@ -702,8 +703,8 @@ describe('ContributionResolver', () => { describe('User deletes already confirmed contribution', () => { it('throws an error', async () => { - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, }) await mutate({ @@ -712,8 +713,8 @@ describe('ContributionResolver', () => { id: result.data.createContribution.id, }, }) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, }) await expect( diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 13715e088..f7671814c 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -4,8 +4,15 @@ import { testEnvironment, headerPushMock, resetToken, cleanDB, resetEntity } from '@test/helpers' import { userFactory } from '@/seeds/factory/user' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' -import { createUser, setPassword, forgotPassword, updateUserInfos } from '@/seeds/graphql/mutations' -import { login, logout, verifyLogin, queryOptIn, searchAdminUsers } from '@/seeds/graphql/queries' +import { + login, + logout, + createUser, + setPassword, + forgotPassword, + updateUserInfos, +} from '@/seeds/graphql/mutations' +import { verifyLogin, queryOptIn, searchAdminUsers } from '@/seeds/graphql/queries' import { GraphQLError } from 'graphql' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { User } from '@entity/User' @@ -459,7 +466,7 @@ bei Gradidio sei dabei!`, describe('no users in database', () => { beforeAll(async () => { - result = await query({ query: login, variables }) + result = await mutate({ mutation: login, variables }) }) it('throws an error', () => { @@ -478,7 +485,7 @@ bei Gradidio sei dabei!`, describe('user is in database and correct login data', () => { beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) - result = await query({ query: login, variables }) + result = await mutate({ mutation: login, variables }) }) afterAll(async () => { @@ -515,7 +522,7 @@ bei Gradidio sei dabei!`, describe('user is in database and wrong password', () => { beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) - result = await query({ query: login, variables: { ...variables, password: 'wrong' } }) + result = await mutate({ mutation: login, variables: { ...variables, password: 'wrong' } }) }) afterAll(async () => { @@ -540,7 +547,7 @@ bei Gradidio sei dabei!`, describe('unauthenticated', () => { it('throws an error', async () => { resetToken() - await expect(query({ query: logout })).resolves.toEqual( + await expect(mutate({ mutation: logout })).resolves.toEqual( expect.objectContaining({ errors: [new GraphQLError('401 Unauthorized')], }), @@ -556,7 +563,7 @@ bei Gradidio sei dabei!`, beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) - await query({ query: login, variables }) + await mutate({ mutation: login, variables }) }) afterAll(async () => { @@ -564,7 +571,7 @@ bei Gradidio sei dabei!`, }) it('returns true', async () => { - await expect(query({ query: logout })).resolves.toEqual( + await expect(mutate({ mutation: logout })).resolves.toEqual( expect.objectContaining({ data: { logout: 'true' }, errors: undefined, @@ -613,7 +620,7 @@ bei Gradidio sei dabei!`, } beforeAll(async () => { - await query({ query: login, variables }) + await mutate({ mutation: login, variables }) user = await User.find() }) @@ -781,8 +788,8 @@ bei Gradidio sei dabei!`, describe('authenticated', () => { beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_', @@ -913,8 +920,8 @@ bei Gradidio sei dabei!`, it('can login with new password', async () => { await expect( - query({ - query: login, + mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Bb12345_', @@ -933,8 +940,8 @@ bei Gradidio sei dabei!`, it('cannot login with old password', async () => { await expect( - query({ - query: login, + mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_', @@ -971,8 +978,8 @@ bei Gradidio sei dabei!`, beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) await userFactory(testEnv, peterLustig) - await query({ - query: login, + await mutate({ + mutation: login, variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_', diff --git a/backend/src/seeds/factory/contributionLink.ts b/backend/src/seeds/factory/contributionLink.ts index 5c83b6ad3..c2b4b9bf3 100644 --- a/backend/src/seeds/factory/contributionLink.ts +++ b/backend/src/seeds/factory/contributionLink.ts @@ -1,6 +1,5 @@ import { ApolloServerTestClient } from 'apollo-server-testing' -import { createContributionLink } from '@/seeds/graphql/mutations' -import { login } from '@/seeds/graphql/queries' +import { login, createContributionLink } from '@/seeds/graphql/mutations' import { ContributionLink } from '@model/ContributionLink' import { ContributionLinkInterface } from '@/seeds/contributionLink/ContributionLinkInterface' @@ -8,10 +7,10 @@ export const contributionLinkFactory = async ( client: ApolloServerTestClient, contributionLink: ContributionLinkInterface, ): Promise => { - const { mutate, query } = client + const { mutate } = client // login as admin - await query({ query: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } }) + await mutate({ mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } }) const variables = { amount: contributionLink.amount, diff --git a/backend/src/seeds/factory/creation.ts b/backend/src/seeds/factory/creation.ts index d3f0f78ca..e93faa372 100644 --- a/backend/src/seeds/factory/creation.ts +++ b/backend/src/seeds/factory/creation.ts @@ -1,8 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import { adminCreateContribution, confirmContribution } from '@/seeds/graphql/mutations' -import { login } from '@/seeds/graphql/queries' +import { login, adminCreateContribution, confirmContribution } from '@/seeds/graphql/mutations' import { CreationInterface } from '@/seeds/creation/CreationInterface' import { ApolloServerTestClient } from 'apollo-server-testing' import { User } from '@entity/User' @@ -18,9 +17,9 @@ export const creationFactory = async ( client: ApolloServerTestClient, creation: CreationInterface, ): Promise => { - const { mutate, query } = client + const { mutate } = client - await query({ query: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } }) + await mutate({ mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } }) // TODO it would be nice to have this mutation return the id await mutate({ mutation: adminCreateContribution, variables: { ...creation } }) diff --git a/backend/src/seeds/factory/transactionLink.ts b/backend/src/seeds/factory/transactionLink.ts index 2f54dc70c..be5a01d22 100644 --- a/backend/src/seeds/factory/transactionLink.ts +++ b/backend/src/seeds/factory/transactionLink.ts @@ -1,6 +1,5 @@ import { ApolloServerTestClient } from 'apollo-server-testing' -import { createTransactionLink } from '@/seeds/graphql/mutations' -import { login } from '@/seeds/graphql/queries' +import { login, createTransactionLink } from '@/seeds/graphql/mutations' import { TransactionLinkInterface } from '@/seeds/transactionLink/TransactionLinkInterface' import { transactionLinkExpireDate } from '@/graphql/resolver/TransactionLinkResolver' import { TransactionLink } from '@entity/TransactionLink' @@ -9,10 +8,13 @@ export const transactionLinkFactory = async ( client: ApolloServerTestClient, transactionLink: TransactionLinkInterface, ): Promise => { - const { mutate, query } = client + const { mutate } = client // login - await query({ query: login, variables: { email: transactionLink.email, password: 'Aa12345_' } }) + await mutate({ + mutation: login, + variables: { email: transactionLink.email, password: 'Aa12345_' }, + }) const variables = { amount: transactionLink.amount, diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index e5f290645..1d47b61d9 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -289,3 +289,27 @@ export const adminCreateContributionMessage = gql` } } ` + +export const login = gql` + mutation ($email: String!, $password: String!, $publisherId: Int) { + login(email: $email, password: $password, publisherId: $publisherId) { + id + email + firstName + lastName + language + klickTipp { + newsletterState + } + hasElopage + publisherId + isAdmin + } + } +` + +export const logout = gql` + mutation { + logout + } +` diff --git a/backend/src/seeds/graphql/queries.ts b/backend/src/seeds/graphql/queries.ts index 60dffa21b..97f871235 100644 --- a/backend/src/seeds/graphql/queries.ts +++ b/backend/src/seeds/graphql/queries.ts @@ -1,23 +1,5 @@ import gql from 'graphql-tag' -export const login = gql` - query ($email: String!, $password: String!, $publisherId: Int) { - login(email: $email, password: $password, publisherId: $publisherId) { - id - email - firstName - lastName - language - klickTipp { - newsletterState - } - hasElopage - publisherId - isAdmin - } - } -` - export const verifyLogin = gql` query { verifyLogin { @@ -35,12 +17,6 @@ export const verifyLogin = gql` } ` -export const logout = gql` - query { - logout - } -` - export const queryOptIn = gql` query ($optIn: String!) { queryOptIn(optIn: $optIn) From 98aca9ff524f04775a301c66aa144d9da6cf39d0 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 22 Sep 2022 12:29:03 +0200 Subject: [PATCH 08/57] Change the tests setup to the call of mutations instead of queries. --- frontend/src/layouts/DashboardLayout.spec.js | 10 ++++++---- frontend/src/layouts/DashboardLayout.vue | 1 - frontend/src/pages/Login.spec.js | 10 +++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/frontend/src/layouts/DashboardLayout.spec.js b/frontend/src/layouts/DashboardLayout.spec.js index 398724201..846974781 100644 --- a/frontend/src/layouts/DashboardLayout.spec.js +++ b/frontend/src/layouts/DashboardLayout.spec.js @@ -18,6 +18,7 @@ const apolloMock = jest.fn().mockResolvedValue({ logout: 'success', }, }) +const apolloQueryMock = jest.fn() describe('DashboardLayout', () => { let wrapper @@ -40,7 +41,8 @@ describe('DashboardLayout', () => { }, }, $apollo: { - query: apolloMock, + mutate: apolloMock, + query: apolloQueryMock, }, $store: { state: { @@ -142,7 +144,7 @@ describe('DashboardLayout', () => { describe('update transactions', () => { beforeEach(async () => { - apolloMock.mockResolvedValue({ + apolloQueryMock.mockResolvedValue({ data: { transactionList: { balance: { @@ -163,7 +165,7 @@ describe('DashboardLayout', () => { }) it('calls the API', () => { - expect(apolloMock).toBeCalledWith( + expect(apolloQueryMock).toBeCalledWith( expect.objectContaining({ variables: { currentPage: 2, @@ -201,7 +203,7 @@ describe('DashboardLayout', () => { describe('update transactions returns error', () => { beforeEach(async () => { - apolloMock.mockRejectedValue({ + apolloQueryMock.mockRejectedValue({ message: 'Ouch!', }) await wrapper diff --git a/frontend/src/layouts/DashboardLayout.vue b/frontend/src/layouts/DashboardLayout.vue index bf33daa83..2a103a574 100755 --- a/frontend/src/layouts/DashboardLayout.vue +++ b/frontend/src/layouts/DashboardLayout.vue @@ -84,7 +84,6 @@ export default { this.$router.push('/login') }) .catch(() => { - console.log('TESTTEST') this.$store.dispatch('logout') if (this.$router.currentRoute.path !== '/login') this.$router.push('/login') }) diff --git a/frontend/src/pages/Login.spec.js b/frontend/src/pages/Login.spec.js index 6359d07c6..90e98cd44 100644 --- a/frontend/src/pages/Login.spec.js +++ b/frontend/src/pages/Login.spec.js @@ -5,7 +5,7 @@ import Login from './Login' const localVue = global.localVue -const apolloQueryMock = jest.fn() +const apolloMutateMock = jest.fn() const mockStoreDispach = jest.fn() const mockStoreCommit = jest.fn() const mockRouterPush = jest.fn() @@ -41,7 +41,7 @@ describe('Login', () => { params: {}, }, $apollo: { - query: apolloQueryMock, + mutate: apolloMutateMock, }, } @@ -113,7 +113,7 @@ describe('Login', () => { await wrapper.find('input[placeholder="Email"]').setValue('user@example.org') await wrapper.find('input[placeholder="form.password"]').setValue('1234') await flushPromises() - apolloQueryMock.mockResolvedValue({ + apolloMutateMock.mockResolvedValue({ data: { login: 'token', }, @@ -123,7 +123,7 @@ describe('Login', () => { }) it('calls the API with the given data', () => { - expect(apolloQueryMock).toBeCalledWith( + expect(apolloMutateMock).toBeCalledWith( expect.objectContaining({ variables: { email: 'user@example.org', @@ -175,7 +175,7 @@ describe('Login', () => { describe('login fails', () => { const createError = async (errorMessage) => { - apolloQueryMock.mockRejectedValue({ + apolloMutateMock.mockRejectedValue({ message: errorMessage, }) wrapper = Wrapper() From 61f59a259426bb784f97d4878fb2f5585c000998 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 22 Sep 2022 12:34:03 +0200 Subject: [PATCH 09/57] Remove query of contribution message resolver test since it is never used. --- .../src/graphql/resolver/ContributionMessageResolver.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/ContributionMessageResolver.test.ts b/backend/src/graphql/resolver/ContributionMessageResolver.test.ts index bc85c9d58..612c2d20b 100644 --- a/backend/src/graphql/resolver/ContributionMessageResolver.test.ts +++ b/backend/src/graphql/resolver/ContributionMessageResolver.test.ts @@ -22,14 +22,13 @@ jest.mock('@/mailer/sendAddedContributionMessageEmail', () => { } }) -let mutate: any, query: any, con: any +let mutate: any, con: any let testEnv: any let result: any beforeAll(async () => { testEnv = await testEnvironment() mutate = testEnv.mutate - query = testEnv.query con = testEnv.con await cleanDB() }) From 3dd66b4527cc37953c2fa6968153b40dc2b10084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Fri, 23 Sep 2022 00:31:33 +0200 Subject: [PATCH 10/57] small changes in log-pattern Merge remote-tracking branch 'origin/master' into 2220-feature-reconfigure-log4js --- backend/log4js-config.json | 22 ++++++++++---------- backend/src/graphql/resolver/UserResolver.ts | 1 + 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/backend/log4js-config.json b/backend/log4js-config.json index a096713ec..e595e7c52 100644 --- a/backend/log4js-config.json +++ b/backend/log4js-config.json @@ -8,7 +8,7 @@ "pattern": "yyyy-MM-dd", "layout": { - "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" }, "keepFileExt" : true, "fileNameSep" : "_", @@ -21,7 +21,7 @@ "pattern": "yyyy-MM-dd", "layout": { - "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" }, "keepFileExt" : true, "fileNameSep" : "_", @@ -34,7 +34,7 @@ "pattern": "yyyy-MM-dd", "layout": { - "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" }, "keepFileExt" : true, "fileNameSep" : "_", @@ -47,7 +47,7 @@ "pattern": "yyyy-MM-dd", "layout": { - "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" }, "keepFileExt" : true, "fileNameSep" : "_", @@ -60,7 +60,7 @@ "pattern": "yyyy-MM-dd", "layout": { - "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" }, "keepFileExt" : true, "fileNameSep" : "_", @@ -77,7 +77,7 @@ "type": "stdout", "layout": { - "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" } }, "apolloOut": @@ -85,7 +85,7 @@ "type": "stdout", "layout": { - "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] %m" + "type": "pattern", "pattern": "%d{ISO8601} %p %c [%X{user}] [%f : %l] - %m" } } }, @@ -99,7 +99,7 @@ "errors" ], "level": "debug", - "enableCallStack": false + "enableCallStack": true }, "apollo": { @@ -110,7 +110,7 @@ "errors" ], "level": "debug", - "enableCallStack": false + "enableCallStack": true }, "backend": { @@ -121,7 +121,7 @@ "errors" ], "level": "debug", - "enableCallStack": false + "enableCallStack": true }, "klicktipp": { @@ -132,7 +132,7 @@ "errors" ], "level": "debug", - "enableCallStack": false + "enableCallStack": true }, "http": { diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 647bf4fc1..1f05a5162 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -510,6 +510,7 @@ export class UserResolver { @Authorized([RIGHTS.SEND_RESET_PASSWORD_EMAIL]) @Mutation(() => Boolean) async forgotPassword(@Arg('email') email: string): Promise { + logger.addContext('user', 'unknown') logger.info(`forgotPassword(${email})...`) email = email.trim().toLowerCase() const user = await DbUser.findOne({ email }) From 54266349bc87253190fb6d59004b2122039a69d8 Mon Sep 17 00:00:00 2001 From: jjimenezgarcia <99907380+jjimenezgarcia@users.noreply.github.com> Date: Mon, 26 Sep 2022 22:44:10 +0200 Subject: [PATCH 11/57] Refactor: Add all events to documentation table Added missing events to the table. Events implemented on #2231 --- .../BusinessEventProtocol.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md b/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md index ecdf8df34..13a32cce3 100644 --- a/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md +++ b/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md @@ -68,7 +68,7 @@ The following table lists for each event type the mapping between old and new ke | VISIT_GRADIDO | VisitGradidoEvent | x | x | x | | | | | | | | REGISTER | RegisterEvent | x | x | x | x | | | | | | | LOGIN | LoginEvent | x | x | x | x | | | | | | -| | VerifyRedeemEvent | | | | | | | | | | +| VERIFY_REDEEM | VerifyRedeemEvent | x | x | x | x | | | (x) | (x) | | | REDEEM_REGISTER | RedeemRegisterEvent | x | x | x | x | | | (x) | (x) | | | REDEEM_LOGIN | RedeemLoginEvent | x | x | x | x | | | (x) | (x) | | | ACTIVATE_ACCOUNT | ActivateAccountEvent | x | x | x | x | | | | | | @@ -82,20 +82,20 @@ The following table lists for each event type the mapping between old and new ke | TRANSACTION_SEND_REDEEM | TransactionLinkRedeemEvent | x | x | x | x | x | x | x | | x | | CONTRIBUTION_CREATE | ContributionCreateEvent | x | x | x | x | | | | x | x | | CONTRIBUTION_CONFIRM | ContributionConfirmEvent | x | x | x | x | x | x | | x | x | -| | ContributionDenyEvent | x | x | x | x | x | x | | x | x | +| CONTRIBUTION_DENY | ContributionDenyEvent | x | x | x | x | x | x | | x | x | | CONTRIBUTION_LINK_DEFINE | ContributionLinkDefineEvent | x | x | x | x | | | | | x | | CONTRIBUTION_LINK_ACTIVATE_REDEEM | ContributionLinkRedeemEvent | x | x | x | x | | | | x | x | -| | UserCreateContributionMessageEvent | x | x | x | x | | | | x | x | -| | AdminCreateContributionMessageEvent | x | x | x | x | | | | x | x | -| | LogoutEvent | x | x | x | x | | | | x | x | +| USER_CREATES_CONTRIBUTION_MESSAGE | UserCreateContributionMessageEvent | x | x | x | x | | | | x | x | +| ADMIN_CREATES_CONTRIBUTION_MESSAGE | AdminCreateContributionMessageEvent | x | x | x | x | | | | x | x | +| LOGOUT | LogoutEvent | x | x | x | x | | | | | | | SEND_CONFIRMATION_EMAIL | SendConfirmEmailEvent | x | x | x | x | | | | | | -| | SendAccountMultiRegistrationEmailEvent | x | x | x | x | | | | | | -| | SendForgotPasswordEmailEvent | x | x | x | x | | | | | | -| | SendTransactionSendEmailEvent | x | x | x | x | x | x | x | | x | -| | SendTransactionReceiveEmailEvent | x | x | x | x | x | x | x | | x | -| | SendAddedContributionEmailEvent | x | x | x | x | | | | x | x | -| | SendContributionConfirmEmailEvent | x | x | x | x | | | | x | x | -| | SendTransactionLinkRedeemEmailEvent | x | x | x | x | x | x | x | | x | +| SEND_ACCOUNT_MULTIREGISTRATION_EMAIL | SendAccountMultiRegistrationEmailEvent | x | x | x | x | | | | | | +| SEND_FORGOT_PASSWORD_EMAIL | SendForgotPasswordEmailEvent | x | x | x | x | | | | | | +| SEND_TRANSACTION_SEND_EMAIL | SendTransactionSendEmailEvent | x | x | x | x | x | x | x | | x | +| SEND_TRANSACTION_RECEIVE_EMAIL | SendTransactionReceiveEmailEvent | x | x | x | x | x | x | x | | x | +| SEND_ADDED_CONTRIBUTION_EMAIL | SendAddedContributionEmailEvent | x | x | x | x | | | | x | x | +| SEND_CONTRIBUTION_CONFIRM_EMAIL | SendContributionConfirmEmailEvent | x | x | x | x | | | | x | x | +| SEND_TRANSACTION_LINK_REDEEM_EMAIL | SendTransactionLinkRedeemEmailEvent | x | x | x | x | x | x | x | | x | | TRANSACTION_REPEATE_REDEEM | - | | | | | | | | | | | TRANSACTION_RECEIVE_REDEEM | - | | | | | | | | | | From bc11a4a5baec9e80bd2613aec039d841919ab3ac Mon Sep 17 00:00:00 2001 From: joseji Date: Thu, 29 Sep 2022 12:26:28 +0200 Subject: [PATCH 12/57] headers fix --- docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md b/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md index 13a32cce3..dfafe11dd 100644 --- a/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md +++ b/docu/Concepts/TechnicalRequirements/BusinessEventProtocol.md @@ -62,7 +62,7 @@ The business events will be stored in database in the new table `EventProtocol`. The following table lists for each event type the mapping between old and new key, the mandatory attributes, which have to be initialized at event occurence and to be written in the database event protocol table: -| EventType - old key | EventType - new key | id | type | createdAt | userID | XuserID | XCommunityID | transactionID | contribID | amount | +| EventKey | EventType | id | type | createdAt | userID | XuserID | XCommunityID | transactionID | contribID | amount | | :-------------------------------- | :------------------------------------- | :-: | :--: | :-------: | :----: | :-----: | :----------: | :-----------: | :-------: | :----: | | BASIC | BasicEvent | x | x | x | | | | | | | | VISIT_GRADIDO | VisitGradidoEvent | x | x | x | | | | | | | From 55453b217b35da34c3966ec9c5e696e1b4d6eda0 Mon Sep 17 00:00:00 2001 From: mahula Date: Thu, 29 Sep 2022 12:37:30 +0200 Subject: [PATCH 13/57] admin frontend: merge components - functionality of slot compoments IsModerator and IsNotModerator is added to component ContributionMessagesListItem - the slot components are removed, since not required anymore --- .../slots/ContributionMessagesListItem.vue | 37 +++++++++++++++---- .../slots/IsModerator.vue | 37 ------------------- .../slots/IsNotModerator.vue | 34 ----------------- 3 files changed, 29 insertions(+), 79 deletions(-) delete mode 100644 admin/src/components/ContributionMessages/slots/IsModerator.vue delete mode 100644 admin/src/components/ContributionMessages/slots/IsNotModerator.vue diff --git a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue index fa5bdd940..b0630d0b4 100644 --- a/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue +++ b/admin/src/components/ContributionMessages/slots/ContributionMessagesListItem.vue @@ -1,19 +1,24 @@ + diff --git a/admin/src/components/ContributionMessages/slots/IsModerator.vue b/admin/src/components/ContributionMessages/slots/IsModerator.vue deleted file mode 100644 index 0224e042f..000000000 --- a/admin/src/components/ContributionMessages/slots/IsModerator.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - diff --git a/admin/src/components/ContributionMessages/slots/IsNotModerator.vue b/admin/src/components/ContributionMessages/slots/IsNotModerator.vue deleted file mode 100644 index 64946c557..000000000 --- a/admin/src/components/ContributionMessages/slots/IsNotModerator.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - From 899b74d60a4b83317fc4c1e8fbcef5810e3d1cb8 Mon Sep 17 00:00:00 2001 From: mahula Date: Thu, 29 Sep 2022 12:39:21 +0200 Subject: [PATCH 14/57] wallet frontend: merge components - functionality of slot compoments IsModerator and IsNotModerator is added to component ContributionMessagesListItem - the slot components are removed, since not required anymore --- .../ContributionMessagesListItem.vue | 39 ++++++++++++++----- .../slots/IsModerator.vue | 34 ---------------- .../slots/IsNotModerator.vue | 36 ----------------- 3 files changed, 30 insertions(+), 79 deletions(-) delete mode 100644 frontend/src/components/ContributionMessages/slots/IsModerator.vue delete mode 100644 frontend/src/components/ContributionMessages/slots/IsNotModerator.vue diff --git a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue index 5fde8f825..85d371250 100644 --- a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue +++ b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue @@ -1,19 +1,24 @@ - + diff --git a/frontend/src/components/ContributionMessages/slots/IsModerator.vue b/frontend/src/components/ContributionMessages/slots/IsModerator.vue deleted file mode 100644 index 343b92d97..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsModerator.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue b/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue deleted file mode 100644 index 8efca7270..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - From 14aa976e5a1c1ce19e6807a250f0dba54bfcfa3a Mon Sep 17 00:00:00 2001 From: mahula Date: Tue, 4 Oct 2022 12:11:23 +0200 Subject: [PATCH 15/57] wallet frontend: adapt unit tests for merged components - add tests to ContributionMessagesListItem.spec.js - remove slots tests --- .../ContributionMessagesListItem.spec.js | 127 +++++++++++++++--- .../ContributionMessagesListItem.vue | 4 +- .../slots/IsModerator.spec.js | 49 ------- .../slots/IsNotModerator.spec.js | 49 ------- 4 files changed, 110 insertions(+), 119 deletions(-) delete mode 100644 frontend/src/components/ContributionMessages/slots/IsModerator.spec.js delete mode 100644 frontend/src/components/ContributionMessages/slots/IsNotModerator.spec.js diff --git a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.spec.js b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.spec.js index b9f6f0029..74cab882d 100644 --- a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.spec.js +++ b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.spec.js @@ -1,29 +1,29 @@ import { mount } from '@vue/test-utils' import ContributionMessagesList from './ContributionMessagesList.vue' +import ContributionMessagesListItem from './ContributionMessagesListItem.vue' const localVue = global.localVue +let wrapper + +const mocks = { + $t: jest.fn((t) => t), + $d: jest.fn((d) => d), + $store: { + state: { + firstName: 'Peter', + lastName: 'Lustig', + }, + }, +} describe('ContributionMessagesList', () => { - let wrapper - - const mocks = { - $t: jest.fn((t) => t), - $d: jest.fn((d) => d), - $store: { - state: { - firstName: 'Peter', - lastName: 'Lustig', - }, - }, - } - const propsData = { contributionId: 42, - state: 'PENDING0', + state: 'PENDING', messages: [ { id: 111, - message: 'asd asda sda sda', + message: 'Lorem ipsum?', createdAt: '2022-08-29T12:23:27.000Z', updatedAt: null, type: 'DIALOG', @@ -32,10 +32,21 @@ describe('ContributionMessagesList', () => { userId: 107, __typename: 'ContributionMessage', }, + { + id: 113, + message: 'Asda sdad ad asdasd, das Ass das Das. ', + createdAt: '2022-08-29T12:25:34.000Z', + updatedAt: null, + type: 'DIALOG', + userFirstName: 'Bibi', + userLastName: 'Bloxberg', + userId: 108, + __typename: 'ContributionMessage', + }, ], } - const Wrapper = () => { + const ListWrapper = () => { return mount(ContributionMessagesList, { localVue, mocks, @@ -45,11 +56,89 @@ describe('ContributionMessagesList', () => { describe('mount', () => { beforeEach(() => { - wrapper = Wrapper() + wrapper = ListWrapper() }) - it('has a DIV .contribution-messages-list-item', () => { - expect(wrapper.find('div.contribution-messages-list-item').exists()).toBe(true) + it('has two DIV .contribution-messages-list-item elements', () => { + expect(wrapper.findAll('div.contribution-messages-list-item').length).toBe(2) + }) + }) +}) + +describe('ContributionMessagesListItem', () => { + describe('if message author has moderator role', () => { + const propsData = { + message: { + id: 113, + message: 'Asda sdad ad asdasd, das Ass das Das. ', + createdAt: '2022-08-29T12:25:34.000Z', + updatedAt: null, + type: 'DIALOG', + userFirstName: 'Bibi', + userLastName: 'Bloxberg', + userId: 108, + __typename: 'ContributionMessage', + }, + } + + const ItemWrapper = () => { + return mount(ContributionMessagesListItem, { + localVue, + mocks, + propsData, + }) + } + + describe('mount', () => { + beforeAll(() => { + wrapper = ItemWrapper() + }) + + it('has a DIV .is-moderator.text-left', () => { + expect(wrapper.find('div.is-moderator.text-left').exists()).toBe(true) + }) + + it('props.message.default', () => { + expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) + }) + }) + }) + + describe('if message author does not have moderator role', () => { + const propsData = { + message: { + id: 111, + message: 'Lorem ipsum?', + createdAt: '2022-08-29T12:23:27.000Z', + updatedAt: null, + type: 'DIALOG', + userFirstName: 'Peter', + userLastName: 'Lustig', + userId: 107, + __typename: 'ContributionMessage', + }, + } + + const ModeratorItemWrapper = () => { + return mount(ContributionMessagesListItem, { + localVue, + mocks, + propsData, + }) + } + + describe('mount', () => { + beforeAll(() => { + wrapper = ModeratorItemWrapper() + }) + + it('has a DIV .is-not-moderator.text-right', () => { + expect(wrapper.find('div.is-not-moderator.text-right').exists()).toBe(true) + }) + + it('props.message.default', () => { + expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) + }) }) }) }) diff --git a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue index 85d371250..e2bc50be6 100644 --- a/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue +++ b/frontend/src/components/ContributionMessages/ContributionMessagesListItem.vue @@ -44,7 +44,7 @@ export default {