separate AdminResolver.test into the corresponding parts

This commit is contained in:
Ulf Gebhardt 2022-11-23 22:52:22 +01:00
parent 4554b01b89
commit a2c1b0ff96
Signed by: ulfgebhardt
GPG Key ID: DA6B843E748679C9
5 changed files with 2649 additions and 2676 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -4,26 +4,39 @@
import { transactionLinkCode } from './TransactionLinkResolver'
import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg'
import { peterLustig } from '@/seeds/users/peter-lustig'
import { cleanDB, testEnvironment } from '@test/helpers'
import { cleanDB, testEnvironment, resetToken } from '@test/helpers'
import { creationFactory } from '@/seeds/factory/creation'
import { creations } from '@/seeds/creation/index'
import { userFactory } from '@/seeds/factory/user'
import { transactionLinkFactory } from '@/seeds/factory/transactionLink'
import { transactionLinks } from '@/seeds/transactionLink/index'
import {
login,
createContributionLink,
deleteContributionLink,
updateContributionLink,
redeemTransactionLink,
createContribution,
updateContribution,
} from '@/seeds/graphql/mutations'
import { listTransactionLinksAdmin, listContributionLinks } from '@/seeds/graphql/queries'
import { ContributionLink as DbContributionLink } from '@entity/ContributionLink'
import { User } from '@entity/User'
import { UnconfirmedContribution } from '@model/UnconfirmedContribution'
import Decimal from 'decimal.js-light'
import { GraphQLError } from 'graphql'
import { logger } from '@test/testSetup'
let mutate: any, con: any
let mutate: any, query: any, con: any
let testEnv: any
let user: User
let admin: User
beforeAll(async () => {
testEnv = await testEnvironment()
mutate = testEnv.mutate
query = testEnv.query
con = testEnv.con
await cleanDB()
await userFactory(testEnv, bibiBloxberg)
@ -223,6 +236,885 @@ describe('TransactionLinkResolver', () => {
})
})
})
describe('transaction links list', () => {
const variables = {
userId: 1, // dummy, may be replaced
filters: null,
currentPage: 1,
pageSize: 5,
}
// TODO: there is a test not cleaning up after itself! Fix it!
beforeAll(async () => {
await cleanDB()
resetToken()
})
describe('unauthenticated', () => {
it('returns an error', async () => {
await expect(
query({
query: listTransactionLinksAdmin,
variables,
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('authenticated', () => {
describe('without admin rights', () => {
beforeAll(async () => {
user = await userFactory(testEnv, bibiBloxberg)
await mutate({
mutation: login,
variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
it('returns an error', async () => {
await expect(
query({
query: listTransactionLinksAdmin,
variables,
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('with admin rights', () => {
beforeAll(async () => {
// admin 'peter@lustig.de' has to exists for 'creationFactory'
admin = await userFactory(testEnv, peterLustig)
user = await userFactory(testEnv, bibiBloxberg)
variables.userId = user.id
variables.pageSize = 25
// bibi needs GDDs
const bibisCreation = creations.find((creation) => creation.email === 'bibi@bloxberg.de')
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
await creationFactory(testEnv, bibisCreation!)
// bibis transaktion links
const bibisTransaktionLinks = transactionLinks.filter(
(transactionLink) => transactionLink.email === 'bibi@bloxberg.de',
)
for (let i = 0; i < bibisTransaktionLinks.length; i++) {
await transactionLinkFactory(testEnv, bibisTransaktionLinks[i])
}
// admin: only now log in
await mutate({
mutation: login,
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
describe('without any filters', () => {
it('finds 6 open transaction links and no deleted or redeemed', async () => {
await expect(
query({
query: listTransactionLinksAdmin,
variables,
}),
).resolves.toEqual(
expect.objectContaining({
data: {
listTransactionLinksAdmin: {
linkCount: 6,
linkList: expect.not.arrayContaining([
expect.objectContaining({
memo: 'Leider wollte niemand meine Gradidos zum Neujahr haben :(',
createdAt: expect.any(String),
}),
expect.objectContaining({
memo: 'Da habe ich mich wohl etwas übernommen.',
deletedAt: expect.any(String),
}),
]),
},
},
}),
)
})
})
describe('all filters are null', () => {
it('finds 6 open transaction links and no deleted or redeemed', async () => {
await expect(
query({
query: listTransactionLinksAdmin,
variables: {
...variables,
filters: {
withDeleted: null,
withExpired: null,
withRedeemed: null,
},
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
listTransactionLinksAdmin: {
linkCount: 6,
linkList: expect.not.arrayContaining([
expect.objectContaining({
memo: 'Leider wollte niemand meine Gradidos zum Neujahr haben :(',
createdAt: expect.any(String),
}),
expect.objectContaining({
memo: 'Da habe ich mich wohl etwas übernommen.',
deletedAt: expect.any(String),
}),
]),
},
},
}),
)
})
})
describe('filter with deleted', () => {
it('finds 6 open transaction links, 1 deleted, and no redeemed', async () => {
await expect(
query({
query: listTransactionLinksAdmin,
variables: {
...variables,
filters: {
withDeleted: true,
},
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
listTransactionLinksAdmin: {
linkCount: 7,
linkList: expect.arrayContaining([
expect.not.objectContaining({
memo: 'Leider wollte niemand meine Gradidos zum Neujahr haben :(',
createdAt: expect.any(String),
}),
expect.objectContaining({
memo: 'Da habe ich mich wohl etwas übernommen.',
deletedAt: expect.any(String),
}),
]),
},
},
}),
)
})
})
describe('filter by expired', () => {
it('finds 5 open transaction links, 1 expired, and no redeemed', async () => {
await expect(
query({
query: listTransactionLinksAdmin,
variables: {
...variables,
filters: {
withExpired: true,
},
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
listTransactionLinksAdmin: {
linkCount: 7,
linkList: expect.arrayContaining([
expect.objectContaining({
memo: 'Leider wollte niemand meine Gradidos zum Neujahr haben :(',
createdAt: expect.any(String),
}),
expect.not.objectContaining({
memo: 'Da habe ich mich wohl etwas übernommen.',
deletedAt: expect.any(String),
}),
]),
},
},
}),
)
})
})
// TODO: works not as expected, because 'redeemedAt' and 'redeemedBy' have to be added to the transaktion link factory
describe.skip('filter by redeemed', () => {
it('finds 6 open transaction links, 1 deleted, and no redeemed', async () => {
await expect(
query({
query: listTransactionLinksAdmin,
variables: {
...variables,
filters: {
withDeleted: null,
withExpired: null,
withRedeemed: true,
},
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
listTransactionLinksAdmin: {
linkCount: 6,
linkList: expect.arrayContaining([
expect.not.objectContaining({
memo: 'Leider wollte niemand meine Gradidos zum Neujahr haben :(',
createdAt: expect.any(String),
}),
expect.objectContaining({
memo: 'Yeah, eingelöst!',
redeemedAt: expect.any(String),
redeemedBy: expect.any(Number),
}),
expect.not.objectContaining({
memo: 'Da habe ich mich wohl etwas übernommen.',
deletedAt: expect.any(String),
}),
]),
},
},
}),
)
})
})
})
})
})
describe('Contribution Links', () => {
const now = new Date()
const variables = {
amount: new Decimal(200),
name: 'Dokumenta 2022',
memo: 'Danke für deine Teilnahme an der Dokumenta 2022',
cycle: 'once',
validFrom: new Date(2022, 5, 18).toISOString(),
validTo: new Date(now.getFullYear() + 1, 7, 14).toISOString(),
maxAmountPerMonth: new Decimal(200),
maxPerCycle: 1,
}
describe('unauthenticated', () => {
describe('createContributionLink', () => {
it('returns an error', async () => {
await expect(mutate({ mutation: createContributionLink, variables })).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('listContributionLinks', () => {
it('returns an error', async () => {
await expect(query({ query: listContributionLinks })).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('updateContributionLink', () => {
it('returns an error', async () => {
await expect(
mutate({
mutation: updateContributionLink,
variables: {
...variables,
id: -1,
amount: new Decimal(400),
name: 'Dokumenta 2023',
memo: 'Danke für deine Teilnahme an der Dokumenta 2023',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('deleteContributionLink', () => {
it('returns an error', async () => {
await expect(
mutate({ mutation: deleteContributionLink, variables: { id: -1 } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
})
describe('authenticated', () => {
describe('without admin rights', () => {
beforeAll(async () => {
user = await userFactory(testEnv, bibiBloxberg)
await mutate({
mutation: login,
variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
describe('createContributionLink', () => {
it('returns an error', async () => {
await expect(mutate({ mutation: createContributionLink, variables })).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
// TODO: Set this test in new location to have datas
describe('listContributionLinks', () => {
it('returns an empty object', async () => {
await expect(query({ query: listContributionLinks })).resolves.toEqual(
expect.objectContaining({
data: {
listContributionLinks: {
count: 0,
links: [],
},
},
}),
)
})
})
describe('updateContributionLink', () => {
it('returns an error', async () => {
await expect(
mutate({
mutation: updateContributionLink,
variables: {
...variables,
id: -1,
amount: new Decimal(400),
name: 'Dokumenta 2023',
memo: 'Danke für deine Teilnahme an der Dokumenta 2023',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('deleteContributionLink', () => {
it('returns an error', async () => {
await expect(
mutate({ mutation: deleteContributionLink, variables: { id: -1 } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
})
describe('with admin rights', () => {
beforeAll(async () => {
user = await userFactory(testEnv, peterLustig)
await mutate({
mutation: login,
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
describe('createContributionLink', () => {
it('returns a contribution link object', async () => {
await expect(mutate({ mutation: createContributionLink, variables })).resolves.toEqual(
expect.objectContaining({
data: {
createContributionLink: expect.objectContaining({
id: expect.any(Number),
amount: '200',
code: expect.stringMatching(/^[0-9a-f]{24,24}$/),
link: expect.stringMatching(/^.*?\/CL-[0-9a-f]{24,24}$/),
createdAt: expect.any(String),
name: 'Dokumenta 2022',
memo: 'Danke für deine Teilnahme an der Dokumenta 2022',
validFrom: expect.any(String),
validTo: expect.any(String),
maxAmountPerMonth: '200',
cycle: 'once',
maxPerCycle: 1,
}),
},
}),
)
})
it('has a contribution link stored in db', async () => {
const cls = await DbContributionLink.find()
expect(cls).toHaveLength(1)
expect(cls[0]).toEqual(
expect.objectContaining({
id: expect.any(Number),
name: 'Dokumenta 2022',
memo: 'Danke für deine Teilnahme an der Dokumenta 2022',
validFrom: new Date('2022-06-18T00:00:00.000Z'),
validTo: expect.any(Date),
cycle: 'once',
maxPerCycle: 1,
totalMaxCountOfContribution: null,
maxAccountBalance: null,
minGapHours: null,
createdAt: expect.any(Date),
deletedAt: null,
code: expect.stringMatching(/^[0-9a-f]{24,24}$/),
linkEnabled: true,
amount: expect.decimalEqual(200),
maxAmountPerMonth: expect.decimalEqual(200),
}),
)
})
it('returns an error if missing startDate', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
validFrom: null,
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError('Start-Date is not initialized. A Start-Date must be set!'),
],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'Start-Date is not initialized. A Start-Date must be set!',
)
})
it('returns an error if missing endDate', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
validTo: null,
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('End-Date is not initialized. An End-Date must be set!')],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'End-Date is not initialized. An End-Date must be set!',
)
})
it('returns an error if endDate is before startDate', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
validFrom: new Date('2022-06-18T00:00:00.001Z').toISOString(),
validTo: new Date('2022-06-18T00:00:00.000Z').toISOString(),
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError(`The value of validFrom must before or equals the validTo!`),
],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
`The value of validFrom must before or equals the validTo!`,
)
})
it('returns an error if name is an empty string', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
name: '',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('The name must be initialized!')],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('The name must be initialized!')
})
it('returns an error if name is shorter than 5 characters', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
name: '123',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError(
`The value of 'name' with a length of 3 did not fulfill the requested bounderies min=5 and max=100`,
),
],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
`The value of 'name' with a length of 3 did not fulfill the requested bounderies min=5 and max=100`,
)
})
it('returns an error if name is longer than 100 characters', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
name: '12345678901234567892123456789312345678941234567895123456789612345678971234567898123456789912345678901',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError(
`The value of 'name' with a length of 101 did not fulfill the requested bounderies min=5 and max=100`,
),
],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
`The value of 'name' with a length of 101 did not fulfill the requested bounderies min=5 and max=100`,
)
})
it('returns an error if memo is an empty string', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
memo: '',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('The memo must be initialized!')],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('The memo must be initialized!')
})
it('returns an error if memo is shorter than 5 characters', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
memo: '123',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError(
`The value of 'memo' with a length of 3 did not fulfill the requested bounderies min=5 and max=255`,
),
],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
`The value of 'memo' with a length of 3 did not fulfill the requested bounderies min=5 and max=255`,
)
})
it('returns an error if memo is longer than 255 characters', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
memo: '1234567890123456789212345678931234567894123456789512345678961234567897123456789812345678991234567890123456789012345678921234567893123456789412345678951234567896123456789712345678981234567899123456789012345678901234567892123456789312345678941234567895123456',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError(
`The value of 'memo' with a length of 256 did not fulfill the requested bounderies min=5 and max=255`,
),
],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
`The value of 'memo' with a length of 256 did not fulfill the requested bounderies min=5 and max=255`,
)
})
it('returns an error if amount is not positive', async () => {
await expect(
mutate({
mutation: createContributionLink,
variables: {
...variables,
amount: new Decimal(0),
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError('The amount=0 must be initialized with a positiv value!'),
],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'The amount=0 must be initialized with a positiv value!',
)
})
})
describe('listContributionLinks', () => {
describe('one link in DB', () => {
it('returns the link and count 1', async () => {
await expect(query({ query: listContributionLinks })).resolves.toEqual(
expect.objectContaining({
data: {
listContributionLinks: {
links: expect.arrayContaining([
expect.objectContaining({
amount: '200',
code: expect.stringMatching(/^[0-9a-f]{24,24}$/),
link: expect.stringMatching(/^.*?\/CL-[0-9a-f]{24,24}$/),
createdAt: expect.any(String),
name: 'Dokumenta 2022',
memo: 'Danke für deine Teilnahme an der Dokumenta 2022',
validFrom: expect.any(String),
validTo: expect.any(String),
maxAmountPerMonth: '200',
cycle: 'once',
maxPerCycle: 1,
}),
]),
count: 1,
},
},
}),
)
})
})
})
describe('updateContributionLink', () => {
describe('no valid id', () => {
it('returns an error', async () => {
await expect(
mutate({
mutation: updateContributionLink,
variables: {
...variables,
id: -1,
amount: new Decimal(400),
name: 'Dokumenta 2023',
memo: 'Danke für deine Teilnahme an der Dokumenta 2023',
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('Contribution Link not found to given id.')],
}),
)
})
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Contribution Link not found to given id: -1')
})
describe('valid id', () => {
let linkId: number
beforeAll(async () => {
const links = await query({ query: listContributionLinks })
linkId = links.data.listContributionLinks.links[0].id
})
it('returns updated contribution link object', async () => {
await expect(
mutate({
mutation: updateContributionLink,
variables: {
...variables,
id: linkId,
amount: new Decimal(400),
name: 'Dokumenta 2023',
memo: 'Danke für deine Teilnahme an der Dokumenta 2023',
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
updateContributionLink: {
id: linkId,
amount: '400',
code: expect.stringMatching(/^[0-9a-f]{24,24}$/),
link: expect.stringMatching(/^.*?\/CL-[0-9a-f]{24,24}$/),
createdAt: expect.any(String),
name: 'Dokumenta 2023',
memo: 'Danke für deine Teilnahme an der Dokumenta 2023',
validFrom: expect.any(String),
validTo: expect.any(String),
maxAmountPerMonth: '200',
cycle: 'once',
maxPerCycle: 1,
},
},
}),
)
})
it('updated the DB record', async () => {
await expect(DbContributionLink.findOne(linkId)).resolves.toEqual(
expect.objectContaining({
id: linkId,
name: 'Dokumenta 2023',
memo: 'Danke für deine Teilnahme an der Dokumenta 2023',
amount: expect.decimalEqual(400),
}),
)
})
})
})
describe('deleteContributionLink', () => {
describe('no valid id', () => {
it('returns an error', async () => {
await expect(
mutate({ mutation: deleteContributionLink, variables: { id: -1 } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('Contribution Link not found to given id.')],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Contribution Link not found to given id: -1')
})
})
describe('valid id', () => {
let linkId: number
beforeAll(async () => {
const links = await query({ query: listContributionLinks })
linkId = links.data.listContributionLinks.links[0].id
})
it('returns a date string', async () => {
await expect(
mutate({ mutation: deleteContributionLink, variables: { id: linkId } }),
).resolves.toEqual(
expect.objectContaining({
data: {
deleteContributionLink: expect.any(String),
},
}),
)
})
it('does not list this contribution link anymore', async () => {
await expect(query({ query: listContributionLinks })).resolves.toEqual(
expect.objectContaining({
data: {
listContributionLinks: {
links: [],
count: 0,
},
},
}),
)
})
})
})
})
})
})
})
describe('transactionLinkCode', () => {

View File

@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { objectValuesToArray } from '@/util/utilities'
import { testEnvironment, headerPushMock, resetToken, cleanDB } from '@test/helpers'
import { userFactory } from '@/seeds/factory/user'
import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg'
@ -13,8 +14,11 @@ import {
updateUserInfos,
createContribution,
confirmContribution,
setUserRole,
deleteUser,
unDeleteUser,
} from '@/seeds/graphql/mutations'
import { verifyLogin, queryOptIn, searchAdminUsers } from '@/seeds/graphql/queries'
import { verifyLogin, queryOptIn, searchAdminUsers, searchUsers } from '@/seeds/graphql/queries'
import { GraphQLError } from 'graphql'
import { User } from '@entity/User'
import CONFIG from '@/config'
@ -36,6 +40,8 @@ import { UserContact } from '@entity/UserContact'
import { OptInType } from '../enum/OptInType'
import { UserContactType } from '../enum/UserContactType'
import { bobBaumeister } from '@/seeds/users/bob-baumeister'
import { stephenHawking } from '@/seeds/users/stephen-hawking'
import { garrickOllivander } from '@/seeds/users/garrick-ollivander'
// import { klicktippSignIn } from '@/apis/KlicktippController'
@ -69,6 +75,8 @@ jest.mock('@/apis/KlicktippController', () => {
})
*/
let admin: User
let user: User
let mutate: any, query: any, con: any
let testEnv: any
@ -1159,6 +1167,635 @@ describe('UserResolver', () => {
})
})
})
describe('set user role', () => {
// TODO: there is a test not cleaning up after itself! Fix it!
beforeAll(async () => {
await cleanDB()
resetToken()
})
describe('unauthenticated', () => {
it('returns an error', async () => {
await expect(
mutate({ mutation: setUserRole, variables: { userId: 1, isAdmin: true } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('authenticated', () => {
describe('without admin rights', () => {
beforeAll(async () => {
user = await userFactory(testEnv, bibiBloxberg)
await mutate({
mutation: login,
variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
it('returns an error', async () => {
await expect(
mutate({ mutation: setUserRole, variables: { userId: user.id + 1, isAdmin: true } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('with admin rights', () => {
beforeAll(async () => {
admin = await userFactory(testEnv, peterLustig)
await mutate({
mutation: login,
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
describe('user to get a new role does not exist', () => {
it('throws an error', async () => {
jest.clearAllMocks()
await expect(
mutate({ mutation: setUserRole, variables: { userId: admin.id + 1, isAdmin: true } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError(`Could not find user with userId: ${admin.id + 1}`)],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(`Could not find user with userId: ${admin.id + 1}`)
})
})
describe('change role with success', () => {
beforeAll(async () => {
user = await userFactory(testEnv, bibiBloxberg)
})
describe('user gets new role', () => {
describe('to admin', () => {
it('returns date string', async () => {
const result = await mutate({
mutation: setUserRole,
variables: { userId: user.id, isAdmin: true },
})
expect(result).toEqual(
expect.objectContaining({
data: {
setUserRole: expect.any(String),
},
}),
)
expect(new Date(result.data.setUserRole)).toEqual(expect.any(Date))
})
})
describe('to usual user', () => {
it('returns null', async () => {
await expect(
mutate({ mutation: setUserRole, variables: { userId: user.id, isAdmin: false } }),
).resolves.toEqual(
expect.objectContaining({
data: {
setUserRole: null,
},
}),
)
})
})
})
})
describe('change role with error', () => {
describe('is own role', () => {
it('throws an error', async () => {
jest.clearAllMocks()
await expect(
mutate({ mutation: setUserRole, variables: { userId: admin.id, isAdmin: false } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('Administrator can not change his own role!')],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Administrator can not change his own role!')
})
})
describe('user has already role to be set', () => {
describe('to admin', () => {
it('throws an error', async () => {
jest.clearAllMocks()
await mutate({
mutation: setUserRole,
variables: { userId: user.id, isAdmin: true },
})
await expect(
mutate({ mutation: setUserRole, variables: { userId: user.id, isAdmin: true } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('User is already admin!')],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('User is already admin!')
})
})
describe('to usual user', () => {
it('throws an error', async () => {
jest.clearAllMocks()
await mutate({
mutation: setUserRole,
variables: { userId: user.id, isAdmin: false },
})
await expect(
mutate({ mutation: setUserRole, variables: { userId: user.id, isAdmin: false } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('User is already a usual user!')],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('User is already a usual user!')
})
})
})
})
})
})
})
describe('delete user', () => {
describe('unauthenticated', () => {
it('returns an error', async () => {
await expect(mutate({ mutation: deleteUser, variables: { userId: 1 } })).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('authenticated', () => {
describe('without admin rights', () => {
beforeAll(async () => {
user = await userFactory(testEnv, bibiBloxberg)
await mutate({
mutation: login,
variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
it('returns an error', async () => {
await expect(
mutate({ mutation: deleteUser, variables: { userId: user.id + 1 } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('with admin rights', () => {
beforeAll(async () => {
admin = await userFactory(testEnv, peterLustig)
await mutate({
mutation: login,
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
describe('user to be deleted does not exist', () => {
it('throws an error', async () => {
jest.clearAllMocks()
await expect(
mutate({ mutation: deleteUser, variables: { userId: admin.id + 1 } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError(`Could not find user with userId: ${admin.id + 1}`)],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(`Could not find user with userId: ${admin.id + 1}`)
})
})
describe('delete self', () => {
it('throws an error', async () => {
jest.clearAllMocks()
await expect(
mutate({ mutation: deleteUser, variables: { userId: admin.id } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('Moderator can not delete his own account!')],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Moderator can not delete his own account!')
})
})
describe('delete with success', () => {
beforeAll(async () => {
user = await userFactory(testEnv, bibiBloxberg)
})
it('returns date string', async () => {
const result = await mutate({ mutation: deleteUser, variables: { userId: user.id } })
expect(result).toEqual(
expect.objectContaining({
data: {
deleteUser: expect.any(String),
},
}),
)
expect(new Date(result.data.deleteUser)).toEqual(expect.any(Date))
})
describe('delete deleted user', () => {
it('throws an error', async () => {
jest.clearAllMocks()
await expect(
mutate({ mutation: deleteUser, variables: { userId: user.id } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError(`Could not find user with userId: ${user.id}`)],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(`Could not find user with userId: ${user.id}`)
})
})
})
})
})
})
describe('unDelete user', () => {
describe('unauthenticated', () => {
it('returns an error', async () => {
await expect(mutate({ mutation: unDeleteUser, variables: { userId: 1 } })).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('authenticated', () => {
describe('without admin rights', () => {
beforeAll(async () => {
user = await userFactory(testEnv, bibiBloxberg)
await mutate({
mutation: login,
variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
it('returns an error', async () => {
await expect(
mutate({ mutation: unDeleteUser, variables: { userId: user.id + 1 } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('with admin rights', () => {
beforeAll(async () => {
admin = await userFactory(testEnv, peterLustig)
await mutate({
mutation: login,
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
describe('user to be undelete does not exist', () => {
it('throws an error', async () => {
jest.clearAllMocks()
await expect(
mutate({ mutation: unDeleteUser, variables: { userId: admin.id + 1 } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError(`Could not find user with userId: ${admin.id + 1}`)],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(`Could not find user with userId: ${admin.id + 1}`)
})
})
describe('user to undelete is not deleted', () => {
beforeAll(async () => {
user = await userFactory(testEnv, bibiBloxberg)
})
it('throws an error', async () => {
jest.clearAllMocks()
await expect(
mutate({ mutation: unDeleteUser, variables: { userId: user.id } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('User is not deleted')],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('User is not deleted')
})
describe('undelete deleted user', () => {
beforeAll(async () => {
await mutate({ mutation: deleteUser, variables: { userId: user.id } })
})
it('returns null', async () => {
await expect(
mutate({ mutation: unDeleteUser, variables: { userId: user.id } }),
).resolves.toEqual(
expect.objectContaining({
data: { unDeleteUser: null },
}),
)
})
})
})
})
})
})
describe('search users', () => {
const variablesWithoutTextAndFilters = {
searchText: '',
currentPage: 1,
pageSize: 25,
filters: null,
}
describe('unauthenticated', () => {
it('returns an error', async () => {
await expect(
query({
query: searchUsers,
variables: {
...variablesWithoutTextAndFilters,
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('authenticated', () => {
describe('without admin rights', () => {
beforeAll(async () => {
user = await userFactory(testEnv, bibiBloxberg)
await mutate({
mutation: login,
variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
it('returns an error', async () => {
await expect(
query({
query: searchUsers,
variables: {
...variablesWithoutTextAndFilters,
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
describe('with admin rights', () => {
const allUsers = {
bibi: expect.objectContaining({
email: 'bibi@bloxberg.de',
}),
garrick: expect.objectContaining({
email: 'garrick@ollivander.com',
}),
peter: expect.objectContaining({
email: 'peter@lustig.de',
}),
stephen: expect.objectContaining({
email: 'stephen@hawking.uk',
}),
}
beforeAll(async () => {
admin = await userFactory(testEnv, peterLustig)
await mutate({
mutation: login,
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
})
await userFactory(testEnv, bibiBloxberg)
await userFactory(testEnv, stephenHawking)
await userFactory(testEnv, garrickOllivander)
})
afterAll(async () => {
await cleanDB()
resetToken()
})
describe('without any filters', () => {
it('finds all users', async () => {
await expect(
query({
query: searchUsers,
variables: {
...variablesWithoutTextAndFilters,
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
searchUsers: {
userCount: 4,
userList: expect.arrayContaining(objectValuesToArray(allUsers)),
},
},
}),
)
})
})
describe('all filters are null', () => {
it('finds all users', async () => {
await expect(
query({
query: searchUsers,
variables: {
...variablesWithoutTextAndFilters,
filters: {
byActivated: null,
byDeleted: null,
},
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
searchUsers: {
userCount: 4,
userList: expect.arrayContaining(objectValuesToArray(allUsers)),
},
},
}),
)
})
})
describe('filter by unchecked email', () => {
it('finds only users with unchecked email', async () => {
await expect(
query({
query: searchUsers,
variables: {
...variablesWithoutTextAndFilters,
filters: {
byActivated: false,
byDeleted: null,
},
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
searchUsers: {
userCount: 1,
userList: expect.arrayContaining([allUsers.garrick]),
},
},
}),
)
})
})
describe('filter by deleted users', () => {
it('finds only users with deleted account', async () => {
await expect(
query({
query: searchUsers,
variables: {
...variablesWithoutTextAndFilters,
filters: {
byActivated: null,
byDeleted: true,
},
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
searchUsers: {
userCount: 1,
userList: expect.arrayContaining([allUsers.stephen]),
},
},
}),
)
})
})
describe('filter by deleted account and unchecked email', () => {
it('finds no users', async () => {
await expect(
query({
query: searchUsers,
variables: {
...variablesWithoutTextAndFilters,
filters: {
byActivated: false,
byDeleted: true,
},
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
searchUsers: {
userCount: 0,
userList: [],
},
},
}),
)
})
})
})
})
})
})
describe('printTimeDuration', () => {

View File

@ -0,0 +1,7 @@
import { contributionDateFormatter } from '@test/helpers'
describe('contributionDateFormatter', () => {
it('formats the date correctly', () => {
expect(contributionDateFormatter(new Date('Thu Feb 29 2024 13:12:11'))).toEqual('2/29/2024')
})
})