Merge remote-tracking branch 'origin/master' into 2215-feature-config-testmodus-flag-for-sending-emails-to-test-or-team-account-instead-of-user-account

This commit is contained in:
Claus-Peter Hübner 2022-09-20 19:23:30 +02:00
commit fa76bd68a1
2 changed files with 96 additions and 11 deletions

View File

@ -19,6 +19,8 @@ import { contributionLinkFactory } from '@/seeds/factory/contributionLink'
import { ContributionLink } from '@model/ContributionLink' import { ContributionLink } from '@model/ContributionLink'
// import { TransactionLink } from '@entity/TransactionLink' // import { TransactionLink } from '@entity/TransactionLink'
import { EventProtocolType } from '@/event/EventProtocolType'
import { EventProtocol } from '@entity/EventProtocol'
import { logger } from '@test/testSetup' import { logger } from '@test/testSetup'
import { validate as validateUUID, version as versionUUID } from 'uuid' import { validate as validateUUID, version as versionUUID } from 'uuid'
import { peterLustig } from '@/seeds/users/peter-lustig' import { peterLustig } from '@/seeds/users/peter-lustig'
@ -169,6 +171,15 @@ describe('UserResolver', () => {
duration: expect.any(String), duration: expect.any(String),
}) })
}) })
it('stores the send confirmation event in the database', () => {
expect(EventProtocol.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventProtocolType.SEND_CONFIRMATION_EMAIL,
userId: user[0].id,
}),
)
})
}) })
describe('email already exists', () => { describe('email already exists', () => {
@ -245,18 +256,26 @@ describe('UserResolver', () => {
mutation: setPassword, mutation: setPassword,
variables: { code: emailOptIn, password: 'Aa12345_' }, variables: { code: emailOptIn, password: 'Aa12345_' },
}) })
// make Peter Lustig Admin // make Peter Lustig Admin
const peter = await User.findOneOrFail({ id: user[0].id }) const peter = await User.findOneOrFail({ id: user[0].id })
peter.isAdmin = new Date() peter.isAdmin = new Date()
await peter.save() await peter.save()
// date statement
const actualDate = new Date()
const futureDate = new Date() // Create a future day from the executed day
futureDate.setDate(futureDate.getDate() + 1)
// factory logs in as Peter Lustig // factory logs in as Peter Lustig
link = await contributionLinkFactory(testEnv, { link = await contributionLinkFactory(testEnv, {
name: 'Dokumenta 2022', name: 'Dokumenta 2022',
memo: 'Vielen Dank für deinen Besuch bei der Dokumenta 2022', memo: 'Vielen Dank für deinen Besuch bei der Dokumenta 2022',
amount: 200, amount: 200,
validFrom: new Date(2022, 5, 18), validFrom: actualDate,
validTo: new Date(2022, 8, 25), validTo: futureDate,
}) })
resetToken() resetToken()
await mutate({ await mutate({
mutation: createUser, mutation: createUser,
@ -271,6 +290,15 @@ describe('UserResolver', () => {
}), }),
) )
}) })
it('stores the account activated event in the database', () => {
expect(EventProtocol.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventProtocolType.ACTIVATE_ACCOUNT,
userId: user[0].id,
}),
)
})
}) })
/* A transaction link requires GDD on account /* A transaction link requires GDD on account
@ -383,6 +411,10 @@ bei Gradidio sei dabei!`,
}), }),
) )
}) })
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Password entered is lexically invalid')
})
}) })
describe('no valid optin code', () => { describe('no valid optin code', () => {
@ -405,6 +437,10 @@ bei Gradidio sei dabei!`,
}), }),
) )
}) })
it('logs the error found', () => {
expect(logger.error).toBeCalledWith('Could not login with emailVerificationCode')
})
}) })
}) })
@ -433,6 +469,10 @@ bei Gradidio sei dabei!`,
}), }),
) )
}) })
it('logs the error found', () => {
expect(logger.error).toBeCalledWith('User with email=bibi@bloxberg.de does not exist')
})
}) })
describe('user is in database and correct login data', () => { describe('user is in database and correct login data', () => {
@ -475,6 +515,7 @@ bei Gradidio sei dabei!`,
describe('user is in database and wrong password', () => { describe('user is in database and wrong password', () => {
beforeAll(async () => { beforeAll(async () => {
await userFactory(testEnv, bibiBloxberg) await userFactory(testEnv, bibiBloxberg)
result = await query({ query: login, variables: { ...variables, password: 'wrong' } })
}) })
afterAll(async () => { afterAll(async () => {
@ -482,14 +523,16 @@ bei Gradidio sei dabei!`,
}) })
it('returns an error', () => { it('returns an error', () => {
expect( expect(result).toEqual(
query({ query: login, variables: { ...variables, password: 'wrong' } }),
).resolves.toEqual(
expect.objectContaining({ expect.objectContaining({
errors: [new GraphQLError('No user with this credentials')], errors: [new GraphQLError('No user with this credentials')],
}), }),
) )
}) })
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('The User has no valid credentials.')
})
}) })
}) })
@ -562,6 +605,8 @@ bei Gradidio sei dabei!`,
}) })
describe('authenticated', () => { describe('authenticated', () => {
let user: User[]
const variables = { const variables = {
email: 'bibi@bloxberg.de', email: 'bibi@bloxberg.de',
password: 'Aa12345_', password: 'Aa12345_',
@ -569,6 +614,7 @@ bei Gradidio sei dabei!`,
beforeAll(async () => { beforeAll(async () => {
await query({ query: login, variables }) await query({ query: login, variables })
user = await User.find()
}) })
afterAll(() => { afterAll(() => {
@ -595,6 +641,15 @@ bei Gradidio sei dabei!`,
}), }),
) )
}) })
it('stores the login event in the database', () => {
expect(EventProtocol.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventProtocolType.LOGIN,
userId: user[0].id,
}),
)
})
}) })
}) })
}) })
@ -649,13 +704,17 @@ bei Gradidio sei dabei!`,
}) })
describe('request reset password again', () => { describe('request reset password again', () => {
it('thows an error', async () => { it('throws an error', async () => {
await expect(mutate({ mutation: forgotPassword, variables })).resolves.toEqual( await expect(mutate({ mutation: forgotPassword, variables })).resolves.toEqual(
expect.objectContaining({ expect.objectContaining({
errors: [new GraphQLError('email already sent less than 10 minutes minutes ago')], errors: [new GraphQLError('email already sent less than 10 minutes minutes ago')],
}), }),
) )
}) })
it('logs the error found', () => {
expect(logger.error).toBeCalledWith(`email already sent less than 10 minutes minutes ago`)
})
}) })
}) })
}) })
@ -766,7 +825,7 @@ bei Gradidio sei dabei!`,
}) })
describe('language is not valid', () => { describe('language is not valid', () => {
it('thows an error', async () => { it('throws an error', async () => {
await expect( await expect(
mutate({ mutate({
mutation: updateUserInfos, mutation: updateUserInfos,
@ -780,6 +839,10 @@ bei Gradidio sei dabei!`,
}), }),
) )
}) })
it('logs the error found', () => {
expect(logger.error).toBeCalledWith(`"not-valid" isn't a valid language`)
})
}) })
describe('password', () => { describe('password', () => {
@ -799,6 +862,10 @@ bei Gradidio sei dabei!`,
}), }),
) )
}) })
it('logs the error found', () => {
expect(logger.error).toBeCalledWith(`Old password is invalid`)
})
}) })
describe('invalid new password', () => { describe('invalid new password', () => {
@ -821,6 +888,10 @@ bei Gradidio sei dabei!`,
}), }),
) )
}) })
it('logs the error found', () => {
expect(logger.error).toBeCalledWith('newPassword does not fullfil the rules')
})
}) })
describe('correct old and new password', () => { describe('correct old and new password', () => {
@ -840,7 +911,7 @@ bei Gradidio sei dabei!`,
) )
}) })
it('can login wtih new password', async () => { it('can login with new password', async () => {
await expect( await expect(
query({ query({
query: login, query: login,
@ -860,7 +931,7 @@ bei Gradidio sei dabei!`,
) )
}) })
it('cannot login wtih old password', async () => { it('cannot login with old password', async () => {
await expect( await expect(
query({ query({
query: login, query: login,
@ -875,6 +946,10 @@ bei Gradidio sei dabei!`,
}), }),
) )
}) })
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('The User has no valid credentials.')
})
}) })
}) })
}) })

View File

@ -30,6 +30,7 @@ import {
EventRedeemRegister, EventRedeemRegister,
EventRegister, EventRegister,
EventSendConfirmationEmail, EventSendConfirmationEmail,
EventActivateAccount,
} from '@/event/Event' } from '@/event/Event'
import { getUserCreation } from './util/creations' import { getUserCreation } from './util/creations'
import { UserRepository } from '@/typeorm/repository/User' import { UserRepository } from '@/typeorm/repository/User'
@ -273,7 +274,7 @@ export class UserResolver {
logger.info(`login with ${email}, ***, ${publisherId} ...`) logger.info(`login with ${email}, ***, ${publisherId} ...`)
email = email.trim().toLowerCase() email = email.trim().toLowerCase()
const dbUser = await DbUser.findOneOrFail({ email }, { withDeleted: true }).catch(() => { const dbUser = await DbUser.findOneOrFail({ email }, { withDeleted: true }).catch(() => {
logger.error(`User with email=${email} does not exists`) logger.error(`User with email=${email} does not exist`)
throw new Error('No user with this credentials') throw new Error('No user with this credentials')
}) })
if (dbUser.deletedAt) { if (dbUser.deletedAt) {
@ -389,7 +390,7 @@ export class UserResolver {
/* uncomment this, when you need the activation link on the console */ /* uncomment this, when you need the activation link on the console */
// In case EMails are disabled log the activation link for the user // In case EMails are disabled log the activation link for the user
if (!emailSent) { if (!emailSent) {
logger.debug(`Email not send!`) logger.debug(`Email not sent!`)
} }
logger.info('createUser() faked and send multi registration mail...') logger.info('createUser() faked and send multi registration mail...')
@ -548,6 +549,7 @@ export class UserResolver {
logger.info(`setPassword(${code}, ***)...`) logger.info(`setPassword(${code}, ***)...`)
// Validate Password // Validate Password
if (!isPassword(password)) { if (!isPassword(password)) {
logger.error('Password entered is lexically invalid')
throw new Error( throw new Error(
'Please enter a valid password with at least 8 characters, upper and lower case letters, at least one number and one special character!', 'Please enter a valid password with at least 8 characters, upper and lower case letters, at least one number and one special character!',
) )
@ -610,6 +612,8 @@ export class UserResolver {
await queryRunner.connect() await queryRunner.connect()
await queryRunner.startTransaction('READ UNCOMMITTED') await queryRunner.startTransaction('READ UNCOMMITTED')
const event = new Event()
try { try {
// Save user // Save user
await queryRunner.manager.save(user).catch((error) => { await queryRunner.manager.save(user).catch((error) => {
@ -618,6 +622,11 @@ export class UserResolver {
}) })
await queryRunner.commitTransaction() await queryRunner.commitTransaction()
const eventActivateAccount = new EventActivateAccount()
eventActivateAccount.userId = user.id
eventProtocol.writeEvent(event.setEventActivateAccount(eventActivateAccount))
logger.info('User data written successfully...') logger.info('User data written successfully...')
} catch (e) { } catch (e) {
await queryRunner.rollbackTransaction() await queryRunner.rollbackTransaction()
@ -727,6 +736,7 @@ export class UserResolver {
try { try {
await queryRunner.manager.save(userEntity).catch((error) => { await queryRunner.manager.save(userEntity).catch((error) => {
logger.error('error saving user: ' + error)
throw new Error('error saving user: ' + error) throw new Error('error saving user: ' + error)
}) })