import { GraphQLClient } from 'graphql-request' import Factory from '../../seed/factories' import { host, login, gql } from '../../jest/helpers' const factory = Factory() let user let badge describe('rewards', () => { const variables = { from: 'indiegogo_en_rhino', to: 'u1', } beforeEach(async () => { user = await factory.create('User', { id: 'u1', role: 'user', email: 'user@example.org', password: '1234', }) await factory.create('User', { id: 'u2', role: 'moderator', email: 'moderator@example.org', }) await factory.create('User', { id: 'u3', role: 'admin', email: 'admin@example.org', }) badge = await factory.create('Badge', { id: 'indiegogo_en_rhino', type: 'crowdfunding', status: 'permanent', icon: '/img/badges/indiegogo_en_rhino.svg', }) }) afterEach(async () => { await factory.cleanDatabase() }) describe('reward', () => { const mutation = gql` mutation($from: ID!, $to: ID!) { reward(badgeKey: $from, userId: $to) { id badges { id } } } ` describe('unauthenticated', () => { let client it('throws authorization error', async () => { client = new GraphQLClient(host) await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') }) }) describe('authenticated admin', () => { let client beforeEach(async () => { const headers = await login({ email: 'admin@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) }) describe('badge for id does not exist', () => { it('rejects with a telling error message', async () => { await expect( client.request(mutation, { ...variables, from: 'bullshit', }), ).rejects.toThrow("Couldn't find a badge with that id") }) }) describe('user for id does not exist', () => { it('rejects with a telling error message', async () => { await expect( client.request(mutation, { ...variables, to: 'bullshit', }), ).rejects.toThrow("Couldn't find a user with that id") }) }) it('rewards a badge to user', async () => { const expected = { reward: { id: 'u1', badges: [{ id: 'indiegogo_en_rhino' }], }, } await expect(client.request(mutation, variables)).resolves.toEqual(expected) }) it('rewards a second different badge to same user', async () => { await factory.create('Badge', { id: 'indiegogo_en_racoon', icon: '/img/badges/indiegogo_en_racoon.svg', }) const badges = [{ id: 'indiegogo_en_racoon' }, { id: 'indiegogo_en_rhino' }] const expected = { reward: { id: 'u1', badges: expect.arrayContaining(badges), }, } await client.request(mutation, variables) await expect( client.request(mutation, { ...variables, from: 'indiegogo_en_racoon', }), ).resolves.toEqual(expected) }) it('rewards the same badge as well to another user', async () => { const expected = { reward: { id: 'u2', badges: [{ id: 'indiegogo_en_rhino' }], }, } await expect( client.request(mutation, { ...variables, to: 'u2', }), ).resolves.toEqual(expected) }) it('creates no duplicate reward relationships', async () => { await client.request(mutation, variables) await client.request(mutation, variables) const query = gql` { User(id: "u1") { badgesCount badges { id } } } ` const expected = { User: [{ badgesCount: 1, badges: [{ id: 'indiegogo_en_rhino' }] }] } await expect(client.request(query)).resolves.toEqual(expected) }) }) describe('authenticated moderator', () => { let client beforeEach(async () => { const headers = await login({ email: 'moderator@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) }) describe('rewards bage to user', () => { it('throws authorization error', async () => { await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') }) }) }) }) describe('unreward', () => { beforeEach(async () => { await user.relateTo(badge, 'rewarded') }) const expected = { unreward: { id: 'u1', badges: [] } } const mutation = gql` mutation($from: ID!, $to: ID!) { unreward(badgeKey: $from, userId: $to) { id badges { id } } } ` describe('check test setup', () => { it('user has one badge', async () => { const query = gql` { User(id: "u1") { badgesCount badges { id } } } ` const expected = { User: [{ badgesCount: 1, badges: [{ id: 'indiegogo_en_rhino' }] }] } const client = new GraphQLClient(host) await expect(client.request(query)).resolves.toEqual(expected) }) }) describe('unauthenticated', () => { let client it('throws authorization error', async () => { client = new GraphQLClient(host) await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') }) }) describe('authenticated admin', () => { let client beforeEach(async () => { const headers = await login({ email: 'admin@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) }) it('removes a badge from user', async () => { await expect(client.request(mutation, variables)).resolves.toEqual(expected) }) it('does not crash when unrewarding multiple times', async () => { await client.request(mutation, variables) await expect(client.request(mutation, variables)).resolves.toEqual(expected) }) }) describe('authenticated moderator', () => { let client beforeEach(async () => { const headers = await login({ email: 'moderator@example.org', password: '1234' }) client = new GraphQLClient(host, { headers }) }) describe('removes bage from user', () => { it('throws authorization error', async () => { await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised') }) }) }) }) })