mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
This is a side quest of #8558. The motivation is to be able to do dependency injection in the tests without overwriting global data. I saw the first merge conflict from #8551 and voila: It seems @Mogge could have used this already. refactor: follow @Mogge's review See: https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/8603#pullrequestreview-2880714796 refactor: better test helper methods wip: continue refactoring wip: continue posts continue wip: continue groups continue registration registration continue messages continue observeposts continue categories continue posts in groups continue invite codes refactor: continue notificationsMiddleware continue statistics spec followed-users online-status mentions-in-groups posts-in-groups email spec finish all tests improve typescript missed one test remove one more reference of CONFIG eliminate one more global import of CONFIG fix language spec test fix two more test suites refactor: completely mock out 3rd part API request refactor test fixed user_management spec fixed more locatoin specs install types for jsonwebtoken one more fetchmock fixed one more suite fix one more spec yet another spec fix spec delete whitespaces remove beforeAll that the same as the default fix merge conflict fix e2e test refactor: use single callback function for `context` setup refactor: display logs from backend during CI Because why not? fix seeds fix login refactor: one unnecessary naming refactor: better editor support refactor: fail early Interestingly, I've had to destructure `context.user` in order to make typescript happy. Weird. refactor: undo changes to workflows - no effect We're running in `--detached` mode on CI, so I guess we won't be able to see the logs anyways. refactor: remove fetch from context after review See: refactor: found an easier way for required props Co-authored-by: Max <maxharz@gmail.com> Co-authored-by: Ulf Gebhardt <ulf.gebhardt@webcraft-media.de>
1174 lines
33 KiB
TypeScript
1174 lines
33 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
import gql from 'graphql-tag'
|
|
|
|
import { TROPHY_BADGES_SELECTED_MAX } from '@constants/badges'
|
|
import Factory, { cleanDatabase } from '@db/factories'
|
|
import { rewardTrophyBadge } from '@graphql/queries/rewardTrophyBadge'
|
|
import { setTrophyBadgeSelected } from '@graphql/queries/setTrophyBadgeSelected'
|
|
import type { ApolloTestSetup } from '@root/test/helpers'
|
|
import { createApolloTestSetup } from '@root/test/helpers'
|
|
import type { Context } from '@src/context'
|
|
|
|
let regularUser, administrator, moderator, badge, verification
|
|
|
|
let authenticatedUser: Context['user']
|
|
const context = () => ({ authenticatedUser })
|
|
let mutate: ApolloTestSetup['mutate']
|
|
let query: ApolloTestSetup['query']
|
|
let database: ApolloTestSetup['database']
|
|
let server: ApolloTestSetup['server']
|
|
|
|
beforeAll(async () => {
|
|
await cleanDatabase()
|
|
const apolloSetup = createApolloTestSetup({ context })
|
|
mutate = apolloSetup.mutate
|
|
query = apolloSetup.query
|
|
database = apolloSetup.database
|
|
server = apolloSetup.server
|
|
})
|
|
|
|
afterAll(() => {
|
|
void server.stop()
|
|
void database.driver.close()
|
|
database.neode.close()
|
|
})
|
|
|
|
describe('Badges', () => {
|
|
beforeEach(async () => {
|
|
regularUser = await Factory.build(
|
|
'user',
|
|
{
|
|
id: 'regular-user-id',
|
|
role: 'user',
|
|
},
|
|
{
|
|
email: 'user@example.org',
|
|
password: '1234',
|
|
},
|
|
)
|
|
moderator = await Factory.build(
|
|
'user',
|
|
{
|
|
id: 'moderator-id',
|
|
role: 'moderator',
|
|
},
|
|
{
|
|
email: 'moderator@example.org',
|
|
},
|
|
)
|
|
administrator = await Factory.build(
|
|
'user',
|
|
{
|
|
id: 'admin-id',
|
|
role: 'admin',
|
|
},
|
|
{
|
|
email: 'admin@example.org',
|
|
},
|
|
)
|
|
badge = await Factory.build('badge', {
|
|
id: 'trophy_rhino',
|
|
type: 'trophy',
|
|
description: 'You earned a rhino',
|
|
icon: '/img/badges/trophy_blue_rhino.svg',
|
|
})
|
|
|
|
verification = await Factory.build('badge', {
|
|
id: 'verification_moderator',
|
|
type: 'verification',
|
|
description: 'You are a moderator',
|
|
icon: '/img/badges/verification_red_moderator.svg',
|
|
})
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await cleanDatabase()
|
|
})
|
|
|
|
describe('setVerificationBadge', () => {
|
|
const variables = {
|
|
badgeId: 'verification_moderator',
|
|
userId: 'regular-user-id',
|
|
}
|
|
|
|
const setVerificationBadgeMutation = gql`
|
|
mutation ($badgeId: ID!, $userId: ID!) {
|
|
setVerificationBadge(badgeId: $badgeId, userId: $userId) {
|
|
id
|
|
badgeVerification {
|
|
id
|
|
isDefault
|
|
}
|
|
badgeTrophies {
|
|
id
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
describe('unauthenticated', () => {
|
|
it('throws authorization error', async () => {
|
|
authenticatedUser = null
|
|
await expect(
|
|
mutate({ mutation: setVerificationBadgeMutation, variables }),
|
|
).resolves.toMatchObject({
|
|
data: { setVerificationBadge: null },
|
|
errors: [{ message: 'Not Authorized!' }],
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('authenticated as moderator', () => {
|
|
beforeEach(() => {
|
|
authenticatedUser = moderator.toJson()
|
|
})
|
|
|
|
describe('rewards badge to user', () => {
|
|
it('throws authorization error', async () => {
|
|
await expect(
|
|
mutate({ mutation: setVerificationBadgeMutation, variables }),
|
|
).resolves.toMatchObject({
|
|
data: { setVerificationBadge: null },
|
|
errors: [{ message: 'Not Authorized!' }],
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('authenticated as admin', () => {
|
|
beforeEach(async () => {
|
|
authenticatedUser = await administrator.toJson()
|
|
})
|
|
|
|
describe('badge for id does not exist', () => {
|
|
it('rejects with an informative error message', async () => {
|
|
await expect(
|
|
mutate({
|
|
mutation: setVerificationBadgeMutation,
|
|
variables: { userId: 'regular-user-id', badgeId: 'non-existent-badge-id' },
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: { setVerificationBadge: null },
|
|
errors: [
|
|
{
|
|
message:
|
|
'Error: Could not reward badge! Ensure the user and the badge exist and the badge is of the correct type.',
|
|
},
|
|
],
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('non-existent user', () => {
|
|
it('rejects with a telling error message', async () => {
|
|
await expect(
|
|
mutate({
|
|
mutation: setVerificationBadgeMutation,
|
|
variables: { userId: 'non-existent-user-id', badgeId: 'verification_moderator' },
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: { setVerificationBadge: null },
|
|
errors: [
|
|
{
|
|
message:
|
|
'Error: Could not reward badge! Ensure the user and the badge exist and the badge is of the correct type.',
|
|
},
|
|
],
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('badge is not a verification badge', () => {
|
|
it('rejects with a telling error message', async () => {
|
|
await expect(
|
|
mutate({
|
|
mutation: setVerificationBadgeMutation,
|
|
variables: { userId: 'regular-user-id', badgeId: 'trophy_rhino' },
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: { setVerificationBadge: null },
|
|
errors: [
|
|
{
|
|
message:
|
|
'Error: Could not reward badge! Ensure the user and the badge exist and the badge is of the correct type.',
|
|
},
|
|
],
|
|
})
|
|
})
|
|
})
|
|
|
|
it('rewards a verification badge to the user', async () => {
|
|
const expected = {
|
|
data: {
|
|
setVerificationBadge: {
|
|
id: 'regular-user-id',
|
|
badgeVerification: { id: 'verification_moderator', isDefault: false },
|
|
badgeTrophies: [],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
}
|
|
await expect(
|
|
mutate({ mutation: setVerificationBadgeMutation, variables }),
|
|
).resolves.toMatchObject(expected)
|
|
})
|
|
|
|
it('overrides the existing verification if a second verification badge is rewarded to the same user', async () => {
|
|
await Factory.build('badge', {
|
|
id: 'verification_admin',
|
|
type: 'verification',
|
|
description: 'You are an admin',
|
|
icon: '/img/badges/verification_red_admin.svg',
|
|
})
|
|
const expected = {
|
|
data: {
|
|
setVerificationBadge: {
|
|
id: 'regular-user-id',
|
|
badgeVerification: { id: 'verification_admin', isDefault: false },
|
|
badgeTrophies: [],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
}
|
|
await mutate({
|
|
mutation: setVerificationBadgeMutation,
|
|
variables: {
|
|
userId: 'regular-user-id',
|
|
badgeId: 'verification_moderator',
|
|
},
|
|
})
|
|
await expect(
|
|
mutate({
|
|
mutation: setVerificationBadgeMutation,
|
|
variables: {
|
|
userId: 'regular-user-id',
|
|
badgeId: 'verification_admin',
|
|
},
|
|
}),
|
|
).resolves.toMatchObject(expected)
|
|
})
|
|
|
|
it('rewards the same verification badge as well to another user', async () => {
|
|
const expected = {
|
|
data: {
|
|
setVerificationBadge: {
|
|
id: 'regular-user-2-id',
|
|
badgeVerification: { id: 'verification_moderator', isDefault: false },
|
|
badgeTrophies: [],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
}
|
|
await Factory.build(
|
|
'user',
|
|
{
|
|
id: 'regular-user-2-id',
|
|
},
|
|
{
|
|
email: 'regular2@email.com',
|
|
},
|
|
)
|
|
await mutate({
|
|
mutation: setVerificationBadgeMutation,
|
|
variables,
|
|
})
|
|
await expect(
|
|
mutate({
|
|
mutation: setVerificationBadgeMutation,
|
|
variables: {
|
|
userId: 'regular-user-2-id',
|
|
badgeId: 'verification_moderator',
|
|
},
|
|
}),
|
|
).resolves.toMatchObject(expected)
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('rewardTrophyBadge', () => {
|
|
const variables = {
|
|
badgeId: 'trophy_rhino',
|
|
userId: 'regular-user-id',
|
|
}
|
|
|
|
describe('unauthenticated', () => {
|
|
it('throws authorization error', async () => {
|
|
authenticatedUser = null
|
|
await expect(mutate({ mutation: rewardTrophyBadge, variables })).resolves.toMatchObject({
|
|
data: { rewardTrophyBadge: null },
|
|
errors: [{ message: 'Not Authorized!' }],
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('authenticated as moderator', () => {
|
|
beforeEach(() => {
|
|
authenticatedUser = moderator.toJson()
|
|
})
|
|
|
|
describe('rewards badge to user', () => {
|
|
it('throws authorization error', async () => {
|
|
await expect(mutate({ mutation: rewardTrophyBadge, variables })).resolves.toMatchObject({
|
|
data: { rewardTrophyBadge: null },
|
|
errors: [{ message: 'Not Authorized!' }],
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('authenticated as admin', () => {
|
|
beforeEach(async () => {
|
|
authenticatedUser = await administrator.toJson()
|
|
})
|
|
|
|
describe('badge for id does not exist', () => {
|
|
it('rejects with an informative error message', async () => {
|
|
await expect(
|
|
mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: { userId: 'regular-user-id', badgeId: 'non-existent-badge-id' },
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: { rewardTrophyBadge: null },
|
|
errors: [
|
|
{
|
|
message:
|
|
'Could not reward badge! Ensure the user and the badge exist and the badge is of the correct type.',
|
|
},
|
|
],
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('non-existent user', () => {
|
|
it('rejects with a telling error message', async () => {
|
|
await expect(
|
|
mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: { userId: 'non-existent-user-id', badgeId: 'trophy_rhino' },
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: { rewardTrophyBadge: null },
|
|
errors: [
|
|
{
|
|
message:
|
|
'Could not reward badge! Ensure the user and the badge exist and the badge is of the correct type.',
|
|
},
|
|
],
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('badge is a verification Badge', () => {
|
|
it('rejects with a telling error message', async () => {
|
|
await expect(
|
|
mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: { userId: 'regular-user-id', badgeId: 'verification_moderator' },
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: { rewardTrophyBadge: null },
|
|
errors: [
|
|
{
|
|
message:
|
|
'Could not reward badge! Ensure the user and the badge exist and the badge is of the correct type.',
|
|
},
|
|
],
|
|
})
|
|
})
|
|
})
|
|
|
|
it('rewards a badge to the user', async () => {
|
|
await expect(mutate({ mutation: rewardTrophyBadge, variables })).resolves.toMatchObject({
|
|
data: {
|
|
rewardTrophyBadge: {
|
|
id: 'regular-user-id',
|
|
badgeVerification: { id: 'default_verification', isDefault: true },
|
|
badgeTrophies: [{ id: 'trophy_rhino' }],
|
|
badgeTrophiesSelected: [
|
|
{ id: 'trophy_rhino' },
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
})
|
|
})
|
|
|
|
it('rewards a second different badge to the same user', async () => {
|
|
await Factory.build('badge', {
|
|
id: 'trophy_racoon',
|
|
type: 'trophy',
|
|
description: 'You earned a racoon',
|
|
icon: '/img/badges/trophy_blue_racoon.svg',
|
|
})
|
|
await mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: {
|
|
userId: 'regular-user-id',
|
|
badgeId: 'trophy_racoon',
|
|
},
|
|
})
|
|
await expect(
|
|
mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: {
|
|
userId: 'regular-user-id',
|
|
badgeId: 'trophy_rhino',
|
|
},
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: {
|
|
rewardTrophyBadge: {
|
|
id: 'regular-user-id',
|
|
badgeTrophies: expect.arrayContaining([
|
|
{ id: 'trophy_racoon' },
|
|
{ id: 'trophy_rhino' },
|
|
]),
|
|
badgeTrophiesSelected: [
|
|
{ id: 'trophy_racoon' },
|
|
{
|
|
id: 'trophy_rhino',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
})
|
|
})
|
|
|
|
it('does not select a badge again when already rewarded and unselected by the user', async () => {
|
|
await Factory.build('badge', {
|
|
id: 'trophy_racoon',
|
|
type: 'trophy',
|
|
description: 'You earned a racoon',
|
|
icon: '/img/badges/trophy_blue_racoon.svg',
|
|
})
|
|
await mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: {
|
|
userId: 'regular-user-id',
|
|
badgeId: 'trophy_rhino',
|
|
},
|
|
})
|
|
await mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: {
|
|
userId: 'regular-user-id',
|
|
badgeId: 'trophy_racoon',
|
|
},
|
|
})
|
|
authenticatedUser = await regularUser.toJson()
|
|
await mutate({
|
|
mutation: setTrophyBadgeSelected,
|
|
variables: {
|
|
slot: 0,
|
|
badgeId: null,
|
|
},
|
|
})
|
|
authenticatedUser = await administrator.toJson()
|
|
await expect(
|
|
mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: {
|
|
userId: 'regular-user-id',
|
|
badgeId: 'trophy_rhino',
|
|
},
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: {
|
|
rewardTrophyBadge: {
|
|
id: 'regular-user-id',
|
|
badgeTrophies: expect.arrayContaining([
|
|
{ id: 'trophy_racoon' },
|
|
{ id: 'trophy_rhino' },
|
|
]),
|
|
badgeTrophiesSelected: [
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{ id: 'trophy_racoon' },
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
})
|
|
})
|
|
|
|
it('does fill gaps in the selection array when rewarding new badges', async () => {
|
|
await Factory.build('badge', {
|
|
id: 'trophy_racoon',
|
|
type: 'trophy',
|
|
description: 'You earned a racoon',
|
|
icon: '/img/badges/trophy_blue_racoon.svg',
|
|
})
|
|
await mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: {
|
|
userId: 'regular-user-id',
|
|
badgeId: 'trophy_rhino',
|
|
},
|
|
})
|
|
authenticatedUser = await regularUser.toJson()
|
|
await mutate({
|
|
mutation: setTrophyBadgeSelected,
|
|
variables: {
|
|
slot: 1,
|
|
badgeId: 'trophy_rhino',
|
|
},
|
|
})
|
|
authenticatedUser = await administrator.toJson()
|
|
await expect(
|
|
mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: {
|
|
userId: 'regular-user-id',
|
|
badgeId: 'trophy_racoon',
|
|
},
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: {
|
|
rewardTrophyBadge: {
|
|
id: 'regular-user-id',
|
|
badgeTrophies: expect.arrayContaining([
|
|
{ id: 'trophy_racoon' },
|
|
{ id: 'trophy_rhino' },
|
|
]),
|
|
badgeTrophiesSelected: [
|
|
{ id: 'trophy_racoon' },
|
|
{ id: 'trophy_rhino' },
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
})
|
|
})
|
|
|
|
it('does not select badge when maximum selected are already reached', async () => {
|
|
for (let i = 0; i < TROPHY_BADGES_SELECTED_MAX; i++) {
|
|
await Factory.build('badge', {
|
|
id: `trophy_${i}`,
|
|
type: 'trophy',
|
|
description: `You earned a ${i}`,
|
|
icon: `/img/badges/trophy_blue_${i}.svg`,
|
|
})
|
|
await mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: {
|
|
userId: 'regular-user-id',
|
|
badgeId: `trophy_${i}`,
|
|
},
|
|
})
|
|
}
|
|
await expect(
|
|
mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: {
|
|
userId: 'regular-user-id',
|
|
badgeId: 'trophy_rhino',
|
|
},
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: {
|
|
rewardTrophyBadge: {
|
|
id: 'regular-user-id',
|
|
badgeTrophies: expect.arrayContaining([
|
|
{ id: 'trophy_0' },
|
|
{ id: 'trophy_1' },
|
|
{ id: 'trophy_2' },
|
|
{ id: 'trophy_3' },
|
|
{ id: 'trophy_4' },
|
|
{ id: 'trophy_5' },
|
|
{ id: 'trophy_6' },
|
|
{ id: 'trophy_7' },
|
|
{ id: 'trophy_8' },
|
|
{ id: 'trophy_rhino' },
|
|
]),
|
|
badgeTrophiesSelected: [
|
|
{ id: 'trophy_0' },
|
|
{ id: 'trophy_1' },
|
|
{ id: 'trophy_2' },
|
|
{ id: 'trophy_3' },
|
|
{ id: 'trophy_4' },
|
|
{ id: 'trophy_5' },
|
|
{ id: 'trophy_6' },
|
|
{ id: 'trophy_7' },
|
|
{ id: 'trophy_8' },
|
|
],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
})
|
|
})
|
|
|
|
it('rewards the same badge as well to another user', async () => {
|
|
await Factory.build(
|
|
'user',
|
|
{
|
|
id: 'regular-user-2-id',
|
|
},
|
|
{
|
|
email: 'regular2@email.com',
|
|
},
|
|
)
|
|
await mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables,
|
|
})
|
|
await expect(
|
|
mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables: {
|
|
userId: 'regular-user-2-id',
|
|
badgeId: 'trophy_rhino',
|
|
},
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: {
|
|
rewardTrophyBadge: {
|
|
id: 'regular-user-2-id',
|
|
badgeTrophies: [{ id: 'trophy_rhino' }],
|
|
badgeTrophiesSelected: [
|
|
{ id: 'trophy_rhino' },
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
})
|
|
})
|
|
|
|
it('creates no duplicate reward relationships', async () => {
|
|
await mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables,
|
|
})
|
|
await expect(
|
|
mutate({
|
|
mutation: rewardTrophyBadge,
|
|
variables,
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: {
|
|
rewardTrophyBadge: {
|
|
id: 'regular-user-id',
|
|
badgeTrophiesCount: 1,
|
|
badgeTrophies: [{ id: 'trophy_rhino' }],
|
|
badgeTrophiesSelected: [
|
|
{ id: 'trophy_rhino' },
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('revokeBadge', () => {
|
|
const variables = {
|
|
badgeId: 'trophy_rhino',
|
|
userId: 'regular-user-id',
|
|
}
|
|
|
|
beforeEach(async () => {
|
|
await regularUser.relateTo(badge, 'rewarded')
|
|
await regularUser.relateTo(verification, 'verifies')
|
|
await regularUser.relateTo(badge, 'selected', { slot: 6 })
|
|
})
|
|
|
|
const revokeBadgeMutation = gql`
|
|
mutation ($badgeId: ID!, $userId: ID!) {
|
|
revokeBadge(badgeId: $badgeId, userId: $userId) {
|
|
id
|
|
badgeTrophies {
|
|
id
|
|
}
|
|
badgeVerification {
|
|
id
|
|
isDefault
|
|
}
|
|
badgeTrophiesSelected {
|
|
id
|
|
isDefault
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
describe('check test setup', () => {
|
|
it('user has one badge and has it selected', async () => {
|
|
authenticatedUser = await regularUser.toJson()
|
|
const userQuery = gql`
|
|
{
|
|
User(id: "regular-user-id") {
|
|
badgeTrophiesCount
|
|
badgeTrophies {
|
|
id
|
|
}
|
|
badgeVerification {
|
|
id
|
|
isDefault
|
|
}
|
|
badgeTrophiesSelected {
|
|
id
|
|
isDefault
|
|
}
|
|
}
|
|
}
|
|
`
|
|
const expected = {
|
|
data: {
|
|
User: [
|
|
{
|
|
badgeTrophiesCount: 1,
|
|
badgeTrophies: [{ id: 'trophy_rhino' }],
|
|
badgeVerification: {
|
|
id: 'verification_moderator',
|
|
isDefault: false,
|
|
},
|
|
badgeTrophiesSelected: [
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'trophy_rhino',
|
|
isDefault: false,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
errors: undefined,
|
|
}
|
|
await expect(query({ query: userQuery })).resolves.toMatchObject(expected)
|
|
})
|
|
})
|
|
|
|
describe('unauthenticated', () => {
|
|
it('throws authorization error', async () => {
|
|
authenticatedUser = null
|
|
await expect(mutate({ mutation: revokeBadgeMutation, variables })).resolves.toMatchObject({
|
|
data: { revokeBadge: null },
|
|
errors: [{ message: 'Not Authorized!' }],
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('authenticated moderator', () => {
|
|
beforeEach(async () => {
|
|
authenticatedUser = await moderator.toJson()
|
|
})
|
|
|
|
describe('removes badge from user', () => {
|
|
it('throws authorization error', async () => {
|
|
await expect(mutate({ mutation: revokeBadgeMutation, variables })).resolves.toMatchObject(
|
|
{
|
|
data: { revokeBadge: null },
|
|
errors: [{ message: 'Not Authorized!' }],
|
|
},
|
|
)
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('authenticated admin', () => {
|
|
beforeEach(async () => {
|
|
authenticatedUser = await administrator.toJson()
|
|
})
|
|
|
|
it('removes a badge from user', async () => {
|
|
await expect(mutate({ mutation: revokeBadgeMutation, variables })).resolves.toMatchObject({
|
|
data: {
|
|
revokeBadge: {
|
|
id: 'regular-user-id',
|
|
badgeVerification: { id: 'verification_moderator', isDefault: false },
|
|
badgeTrophies: [],
|
|
badgeTrophiesSelected: [
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
})
|
|
})
|
|
|
|
it('does not crash when revoking multiple times', async () => {
|
|
await mutate({ mutation: revokeBadgeMutation, variables })
|
|
await expect(mutate({ mutation: revokeBadgeMutation, variables })).resolves.toMatchObject({
|
|
data: {
|
|
revokeBadge: {
|
|
id: 'regular-user-id',
|
|
badgeVerification: { id: 'verification_moderator', isDefault: false },
|
|
badgeTrophies: [],
|
|
badgeTrophiesSelected: [
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
})
|
|
})
|
|
|
|
it('removes a verification from user', async () => {
|
|
await expect(
|
|
mutate({
|
|
mutation: revokeBadgeMutation,
|
|
variables: {
|
|
badgeId: 'verification_moderator',
|
|
userId: 'regular-user-id',
|
|
},
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: {
|
|
revokeBadge: {
|
|
id: 'regular-user-id',
|
|
badgeVerification: { id: 'default_verification', isDefault: true },
|
|
badgeTrophies: [{ id: 'trophy_rhino' }],
|
|
badgeTrophiesSelected: [
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'trophy_rhino',
|
|
isDefault: false,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
})
|
|
})
|
|
|
|
it('does not crash when removing verification multiple times', async () => {
|
|
await mutate({
|
|
mutation: revokeBadgeMutation,
|
|
variables: {
|
|
badgeId: 'verification_moderator',
|
|
userId: 'regular-user-id',
|
|
},
|
|
})
|
|
await expect(
|
|
mutate({
|
|
mutation: revokeBadgeMutation,
|
|
variables: {
|
|
badgeId: 'verification_moderator',
|
|
userId: 'regular-user-id',
|
|
},
|
|
}),
|
|
).resolves.toMatchObject({
|
|
data: {
|
|
revokeBadge: {
|
|
id: 'regular-user-id',
|
|
badgeVerification: { id: 'default_verification', isDefault: true },
|
|
badgeTrophies: [{ id: 'trophy_rhino' }],
|
|
badgeTrophiesSelected: [
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'trophy_rhino',
|
|
isDefault: false,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
{
|
|
id: 'default_trophy',
|
|
isDefault: true,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
errors: undefined,
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|