qyery for generated invite codes

This commit is contained in:
Moriz Wahl 2021-01-12 16:43:34 +01:00
parent dd6cafed4c
commit 9449a55d42
4 changed files with 133 additions and 71 deletions

View File

@ -106,6 +106,7 @@ export default shield(
notifications: isAuthenticated,
Donations: isAuthenticated,
userData: isAuthenticated,
MyInviteCodes: isAuthenticated,
},
Mutation: {
'*': deny,

View File

@ -11,6 +11,30 @@ const uniqueInviteCode = async (session, code) => {
}
export default {
Query: {
MyInviteCodes: async (_parent, args, context, _resolveInfo) => {
const {
user: { id: userId },
} = context
const session = context.driver.session()
const readTxResultPromise = session.readTransaction(async (txc) => {
const result = await txc.run(
`MATCH (user:User {id: $userId})-[:GENERATED]->(ic:InviteCode)
RETURN properties(ic) AS inviteCodes`,
{
userId,
},
)
return result.records.map((record) => record.get('inviteCodes'))
})
try {
const txResult = await readTxResultPromise
return txResult
} finally {
session.close()
}
},
},
Mutation: {
GenerateInviteCode: async (_parent, args, context, _resolveInfo) => {
const {
@ -18,7 +42,6 @@ export default {
} = context
const session = context.driver.session()
let code = generateInvieCode()
let response
while (!(await uniqueInviteCode(session, code))) {
code = generateInvieCode()
}
@ -40,15 +63,15 @@ export default {
})
try {
const txResult = await writeTxResultPromise
response = txResult[0]
return txResult[0]
} finally {
session.close()
}
return response
},
},
InviteCode: {
...Resolver('InviteCode', {
idAttribute: 'code',
undefinedToNull: ['expiresAt'],
hasOne: {
generatedBy: '<-[:GENERATED]-(related:User)',

View File

@ -5,7 +5,7 @@ import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
let user
// let query
let query
let mutate
const driver = getDriver()
@ -20,6 +20,16 @@ const generateInviteCodeMutation = gql`
}
`
const myInviteCodesQuery = gql`
query {
MyInviteCodes {
code
createdAt
expiresAt
}
}
`
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
@ -30,7 +40,7 @@ beforeAll(async () => {
}
},
})
// query = createTestClient(server).query
query = createTestClient(server).query
mutate = createTestClient(server).mutate
})
@ -39,75 +49,99 @@ afterAll(async () => {
})
describe('inviteCodes', () => {
describe('generate invite code', () => {
describe('as unauthenticated user', () => {
it('returns permission denied error', async () => {
await expect(mutate({ mutation: generateInviteCodeMutation })).resolves.toEqual(
expect.objectContaining({
errors: expect.arrayContaining([
expect.objectContaining({
extensions: { code: 'INTERNAL_SERVER_ERROR' },
}),
]),
data: {
GenerateInviteCode: null,
},
}),
)
})
describe('as unauthenticated user', () => {
it('cannot generate invite codes', async () => {
await expect(mutate({ mutation: generateInviteCodeMutation })).resolves.toEqual(
expect.objectContaining({
errors: expect.arrayContaining([
expect.objectContaining({
extensions: { code: 'INTERNAL_SERVER_ERROR' },
}),
]),
data: {
GenerateInviteCode: null,
},
}),
)
})
describe('as authenticated user', () => {
beforeAll(async () => {
const authenticatedUser = await Factory.build(
'user',
{
role: 'user',
it('cannot query invite codes', async () => {
await expect(query({ query: myInviteCodesQuery })).resolves.toEqual(
expect.objectContaining({
errors: expect.arrayContaining([
expect.objectContaining({
extensions: { code: 'INTERNAL_SERVER_ERROR' },
}),
]),
data: {
MyInviteCodes: null,
},
{
email: 'user@example.org',
password: '1234',
},
)
user = await authenticatedUser.toJson()
})
it('generates an invite code without expiresAt', async () => {
await expect(mutate({ mutation: generateInviteCodeMutation })).resolves.toEqual(
expect.objectContaining({
errors: undefined,
data: {
GenerateInviteCode: {
code: expect.stringMatching(/^[0-9A-Z]{6,6}$/),
expiresAt: null,
createdAt: expect.any(String),
},
},
}),
)
})
it('generates an invite code with expiresAt', async () => {
const nextWeek = new Date()
nextWeek.setDate(nextWeek.getDate() + 7)
await expect(
mutate({
mutation: generateInviteCodeMutation,
variables: { expiresAt: nextWeek.toISOString() },
}),
).resolves.toEqual(
expect.objectContaining({
errors: undefined,
data: {
GenerateInviteCode: {
code: expect.stringMatching(/^[0-9A-Z]{6,6}$/),
expiresAt: nextWeek.toISOString(),
createdAt: expect.any(String),
},
},
}),
)
})
}),
)
})
})
describe('as authenticated user', () => {
beforeAll(async () => {
const authenticatedUser = await Factory.build(
'user',
{
role: 'user',
},
{
email: 'user@example.org',
password: '1234',
},
)
user = await authenticatedUser.toJson()
})
it('generates an invite code without expiresAt', async () => {
await expect(mutate({ mutation: generateInviteCodeMutation })).resolves.toEqual(
expect.objectContaining({
errors: undefined,
data: {
GenerateInviteCode: {
code: expect.stringMatching(/^[0-9A-Z]{6,6}$/),
expiresAt: null,
createdAt: expect.any(String),
},
},
}),
)
})
it('generates an invite code with expiresAt', async () => {
const nextWeek = new Date()
nextWeek.setDate(nextWeek.getDate() + 7)
await expect(
mutate({
mutation: generateInviteCodeMutation,
variables: { expiresAt: nextWeek.toISOString() },
}),
).resolves.toEqual(
expect.objectContaining({
errors: undefined,
data: {
GenerateInviteCode: {
code: expect.stringMatching(/^[0-9A-Z]{6,6}$/),
expiresAt: nextWeek.toISOString(),
createdAt: expect.any(String),
},
},
}),
)
})
let inviteCodes
it('returns the created invite codes when queried', async () => {
const response = await query({ query: myInviteCodesQuery })
inviteCodes = response.data.MyInviteCodes
expect(inviteCodes).toHaveLength(2)
})
// const expiringInviteCode = inviteCodes.filter((ic) => ic.expiresAt !== null)
// const unExpiringInviteCode = inviteCodes.filter((ic) => ic.expiresAt === null)
})
})

View File

@ -10,3 +10,7 @@ type InviteCode {
type Mutation {
GenerateInviteCode(expiresAt: String = null): InviteCode
}
type Query {
MyInviteCodes: [InviteCode]
}