unit tests of AdminResolver now with Users and UserContacts

This commit is contained in:
Claus-Peter Hübner 2022-08-31 23:04:55 +02:00
parent faa0500f10
commit eedaf9e6e3
4 changed files with 54 additions and 20 deletions

View File

@ -1117,7 +1117,9 @@ describe('AdminResolver', () => {
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('Could not find user with email: bob@baumeister.de')],
errors: [
new GraphQLError('Could not find UserContact with email: bob@baumeister.de'),
],
}),
)
})

View File

@ -75,24 +75,24 @@ export class AdminResolver {
{ searchText, currentPage = 1, pageSize = 25, filters }: SearchUsersArgs,
): Promise<SearchUsersResult> {
const userRepository = getCustomRepository(UserRepository)
/*
const filterCriteria: ObjectLiteral[] = []
if (filters) {
if (filters.byActivated !== null) {
filterCriteria.push({ emailChecked: filters.byActivated })
filterCriteria.push({ 'emailContact.emailChecked': filters.byActivated })
}
if (filters.byDeleted !== null) {
filterCriteria.push({ deletedAt: filters.byDeleted ? Not(IsNull()) : IsNull() })
}
}
*/
const userFields = [
'id',
'firstName',
'lastName',
'email',
'emailChecked',
'emailId',
'emailContact',
'deletedAt',
'isAdmin',
]
@ -101,7 +101,7 @@ export class AdminResolver {
return 'user.' + fieldName
}),
searchText,
filterCriteria,
filters,
currentPage,
pageSize,
)
@ -249,7 +249,11 @@ export class AdminResolver {
logger.info(
`adminCreateContribution(email=${email}, amount=${amount}, memo=${memo}, creationDate=${creationDate})`,
)
const emailContact = await UserContact.findOne({ email }, { withDeleted: true })
const emailContact = await UserContact.findOne({
where: { email },
withDeleted: true,
relations: ['user'],
})
if (!emailContact) {
logger.error(`Could not find user with email: ${email}`)
throw new Error(`Could not find user with email: ${email}`)
@ -258,6 +262,10 @@ export class AdminResolver {
logger.error('This emailContact was deleted. Cannot create a contribution.')
throw new Error('This emailContact was deleted. Cannot create a contribution.')
}
if (emailContact.user.deletedAt) {
logger.error('This user was deleted. Cannot create a contribution.')
throw new Error('This user was deleted. Cannot create a contribution.')
}
if (!emailContact.emailChecked) {
logger.error('Contribution could not be saved, Email is not activated')
throw new Error('Contribution could not be saved, Email is not activated')
@ -317,12 +325,16 @@ export class AdminResolver {
@Args() { id, email, amount, memo, creationDate }: AdminUpdateContributionArgs,
@Ctx() context: Context,
): Promise<AdminUpdateContribution> {
const emailContact = await UserContact.findOne({ email }, { withDeleted: true })
const emailContact = await UserContact.findOne({
where: { email },
withDeleted: true,
relations: ['user'],
})
if (!emailContact) {
logger.error(`Could not find UserContact with email: ${email}`)
throw new Error(`Could not find UserContact with email: ${email}`)
}
const user = await dbUser.findOne({ id: emailContact.userId }, { withDeleted: true })
const user = emailContact.user
if (!user) {
logger.error(`Could not find User to emailContact: ${email}`)
throw new Error(`Could not find User to emailContact: ${email}`)
@ -388,7 +400,11 @@ export class AdminResolver {
const userIds = contributions.map((p) => p.userId)
const userCreations = await getUserCreations(userIds)
const users = await dbUser.find({ where: { id: In(userIds) }, withDeleted: true })
const users = await dbUser.find({
where: { id: In(userIds) },
withDeleted: true,
relations: ['emailContact'],
})
return contributions.map((contribution) => {
const user = users.find((u) => u.id === contribution.userId)

View File

@ -24,15 +24,16 @@ export const creationFactory = async (
logger.trace('creationFactory...')
await query({ query: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } })
logger.trace('creationFactory... after login')
// TODO it would be nice to have this mutation return the id
await mutate({ mutation: adminCreateContribution, variables: { ...creation } })
logger.trace('creationFactory... after adminCreateContribution')
const userContact = await UserContact.findOneOrFail({ where: { email: creation.email } })
const userContact = await UserContact.findOneOrFail({
where: { email: creation.email },
relations: ['user'],
})
logger.trace('creationFactory... after UserContact.findOneOrFail userContact=', userContact)
const user = await User.findOneOrFail({ where: { id: userContact.userId } })
logger.trace('creationFactory... after User.findOneOrFail user=', user)
const user = userContact.user
const pendingCreation = await Contribution.findOneOrFail({
where: { userId: user.id, amount: creation.amount },
@ -42,12 +43,10 @@ export const creationFactory = async (
'creationFactory... after Contribution.findOneOrFail pendingCreation=',
pendingCreation,
)
if (creation.confirmed) {
logger.trace('creationFactory... creation.confirmed=', creation.confirmed)
await mutate({ mutation: confirmContribution, variables: { id: pendingCreation.id } })
logger.trace('creationFactory... after confirmContribution')
const confirmedCreation = await Contribution.findOneOrFail({ id: pendingCreation.id })
logger.trace(
'creationFactory... after Contribution.findOneOrFail confirmedCreation=',
@ -61,6 +60,7 @@ export const creationFactory = async (
order: { balanceDate: 'DESC' },
})
logger.trace('creationFactory... after Transaction.findOneOrFail transaction=', transaction)
if (transaction.decay.equals(0) && transaction.creationDate) {
confirmedCreation.contributionDate = new Date(
nMonthsBefore(transaction.creationDate, creation.moveCreationDate),

View File

@ -1,4 +1,5 @@
import { Brackets, EntityRepository, ObjectLiteral, Repository } from '@dbTools/typeorm'
import SearchUsersFilters from '@/graphql/arg/SearchUsersFilters'
import { Brackets, EntityRepository, IsNull, Not, Repository } from '@dbTools/typeorm'
import { User as DbUser } from '@entity/User'
@EntityRepository(DbUser)
@ -21,17 +22,18 @@ export class UserRepository extends Repository<DbUser> {
async findBySearchCriteriaPagedFiltered(
select: string[],
searchCriteria: string,
filterCriteria: ObjectLiteral[],
filters: SearchUsersFilters,
currentPage: number,
pageSize: number,
): Promise<[DbUser[], number]> {
const query = this.createQueryBuilder('user')
.select(select)
.leftJoinAndSelect('user.emailContact', 'emailContact')
.withDeleted()
.where(
new Brackets((qb) => {
qb.where(
'user.firstName like :name or user.lastName like :lastName or user.email like :email',
'user.firstName like :name or user.lastName like :lastName or emailContact.email like :email',
{
name: `%${searchCriteria}%`,
lastName: `%${searchCriteria}%`,
@ -40,9 +42,23 @@ export class UserRepository extends Repository<DbUser> {
)
}),
)
/*
filterCriteria.forEach((filter) => {
query.andWhere(filter)
})
*/
if (filters) {
if (filters.byActivated !== null) {
query.andWhere('emailContact.emailChecked = :value', { value: filters.byActivated })
// filterCriteria.push({ 'emailContact.emailChecked': filters.byActivated })
}
if (filters.byDeleted !== null) {
// filterCriteria.push({ deletedAt: filters.byDeleted ? Not(IsNull()) : IsNull() })
query.andWhere({ deletedAt: filters.byDeleted ? Not(IsNull()) : IsNull() })
}
}
return query
.take(pageSize)
.skip((currentPage - 1) * pageSize)