add test for failing to send confirmation email when signup
This commit is contained in:
committed by
Jackson Harper
parent
d284a3d302
commit
068684d16b
@ -1834,6 +1834,7 @@ export enum SignupErrorCode {
|
||||
AccessDenied = 'ACCESS_DENIED',
|
||||
ExpiredToken = 'EXPIRED_TOKEN',
|
||||
GoogleAuthError = 'GOOGLE_AUTH_ERROR',
|
||||
InvalidEmail = 'INVALID_EMAIL',
|
||||
InvalidPassword = 'INVALID_PASSWORD',
|
||||
InvalidUsername = 'INVALID_USERNAME',
|
||||
Unknown = 'UNKNOWN',
|
||||
|
||||
@ -1355,6 +1355,7 @@ enum SignupErrorCode {
|
||||
ACCESS_DENIED
|
||||
EXPIRED_TOKEN
|
||||
GOOGLE_AUTH_ERROR
|
||||
INVALID_EMAIL
|
||||
INVALID_PASSWORD
|
||||
INVALID_USERNAME
|
||||
UNKNOWN
|
||||
|
||||
@ -168,6 +168,7 @@ const schema = gql`
|
||||
USER_EXISTS
|
||||
EXPIRED_TOKEN
|
||||
INVALID_PASSWORD
|
||||
INVALID_EMAIL
|
||||
}
|
||||
|
||||
type GoogleSignupError {
|
||||
|
||||
@ -110,9 +110,11 @@ export const createUser = async (input: {
|
||||
// delete user if email failed to send
|
||||
await AppDataSource.transaction(async (e) => {
|
||||
await setClaims(e, user.id)
|
||||
|
||||
return e.getRepository(User).delete(user.id)
|
||||
})
|
||||
return Promise.reject({ errorCode: SignupErrorCode.Unknown })
|
||||
|
||||
return Promise.reject({ errorCode: SignupErrorCode.InvalidEmail })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -333,6 +333,7 @@ describe('User API', () => {
|
||||
let email: string
|
||||
let password: string
|
||||
let username: string
|
||||
let fake: (msg: MailDataRequired) => Promise<boolean>
|
||||
|
||||
beforeEach(() => {
|
||||
query = `
|
||||
@ -363,29 +364,52 @@ describe('User API', () => {
|
||||
})
|
||||
|
||||
context('when inputs are valid and user not exists', () => {
|
||||
let fake: (msg: MailDataRequired) => Promise<boolean>
|
||||
|
||||
beforeEach(() => {
|
||||
password = correctPassword
|
||||
username = 'Some_username'
|
||||
email = `${username}@fake.com`
|
||||
fake = sinon.replace(util, 'sendEmail', sinon.fake.resolves(true))
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
await deleteTestUser(username)
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
it('responds with 200', async () => {
|
||||
return graphqlRequest(query).expect(200)
|
||||
context('when confirmation email sent', () => {
|
||||
beforeEach(() => {
|
||||
fake = sinon.replace(util, 'sendEmail', sinon.fake.resolves(true))
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
it('responds with 200', async () => {
|
||||
return graphqlRequest(query).expect(200)
|
||||
})
|
||||
|
||||
it('returns the user with the lowercase username', async () => {
|
||||
const res = await graphqlRequest(query).expect(200)
|
||||
expect(res.body.data.signup.me.profile.username).to.eql(
|
||||
username.toLowerCase()
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('returns the user with the lowercase username', async () => {
|
||||
const res = await graphqlRequest(query).expect(200)
|
||||
expect(res.body.data.signup.me.profile.username).to.eql(
|
||||
username.toLowerCase()
|
||||
)
|
||||
context('when confirmation email not sent', () => {
|
||||
before(() => {
|
||||
fake = sinon.replace(util, 'sendEmail', sinon.fake.resolves(false))
|
||||
})
|
||||
|
||||
after(() => {
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
it('responds with error code INVALID_EMAIL', async () => {
|
||||
const res = await graphqlRequest(query).expect(200)
|
||||
expect(res.body.data.signup.errorCodes).to.eql([
|
||||
SignupErrorCode.InvalidEmail,
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -17,71 +17,93 @@ import sinonChai from 'sinon-chai'
|
||||
import sinon from 'sinon'
|
||||
import * as util from '../../src/utils/sendEmail'
|
||||
import { MailDataRequired } from '@sendgrid/helpers/classes/mail'
|
||||
import { getRepository } from '../../src/entity/utils'
|
||||
import { User } from '../../src/entity/user'
|
||||
|
||||
chai.use(sinonChai)
|
||||
|
||||
describe('create a user with an invite', () => {
|
||||
it('follows the other user in the group', async () => {
|
||||
after(async () => {
|
||||
await deleteTestUser(testOwner)
|
||||
await deleteTestUser(testUser)
|
||||
describe('create user', () => {
|
||||
context('create a user with an invite', () => {
|
||||
it('follows the other user in the group', async () => {
|
||||
after(async () => {
|
||||
await deleteTestUser(testOwner)
|
||||
await deleteTestUser(testUser)
|
||||
})
|
||||
|
||||
const testOwner = 'testowner'
|
||||
const testUser = 'testuser'
|
||||
|
||||
const adminUser = await createTestUser(testOwner)
|
||||
const [, invite] = await createGroup({
|
||||
admin: adminUser,
|
||||
name: 'testgroup',
|
||||
})
|
||||
const user = await createTestUser(testUser, invite.code)
|
||||
|
||||
expect(await getUserFollowers(user)).to.eql([adminUser])
|
||||
expect(await getUserFollowing(user)).to.eql([adminUser])
|
||||
expect(await getUserFollowers(adminUser)).to.eql([user])
|
||||
expect(await getUserFollowing(adminUser)).to.eql([user])
|
||||
}).timeout(10000)
|
||||
|
||||
it('creates profile when user exists but profile not', async () => {
|
||||
after(async () => {
|
||||
await deleteTestUser(name)
|
||||
})
|
||||
|
||||
const name = 'userWithoutProfile'
|
||||
const user = await createUserWithoutProfile(name)
|
||||
|
||||
await createTestUser(user.name)
|
||||
|
||||
const profile = await getProfile(user)
|
||||
|
||||
expect(profile).to.exist
|
||||
})
|
||||
})
|
||||
|
||||
context('create a user with pending confirmation', () => {
|
||||
const name = 'pendingUser'
|
||||
let fake: (msg: MailDataRequired) => Promise<boolean>
|
||||
|
||||
context('when email sends successfully', () => {
|
||||
beforeEach(() => {
|
||||
fake = sinon.replace(util, 'sendEmail', sinon.fake.resolves(true))
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
sinon.restore()
|
||||
await deleteTestUser(name)
|
||||
})
|
||||
|
||||
it('creates the user with pending status and correct name', async () => {
|
||||
const user = await createTestUser(name, undefined, undefined, true)
|
||||
|
||||
expect(user.status).to.eql(StatusType.Pending)
|
||||
expect(user.name).to.eql(name)
|
||||
})
|
||||
|
||||
it('sends an email to the user', async () => {
|
||||
await createTestUser(name, undefined, undefined, true)
|
||||
|
||||
expect(fake).to.have.been.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
const testOwner = 'testowner'
|
||||
const testUser = 'testuser'
|
||||
context('when failed to send email', () => {
|
||||
before(() => {
|
||||
fake = sinon.replace(util, 'sendEmail', sinon.fake.resolves(false))
|
||||
})
|
||||
|
||||
const adminUser = await createTestUser(testOwner)
|
||||
const [, invite] = await createGroup({
|
||||
admin: adminUser,
|
||||
name: 'testgroup',
|
||||
after(() => {
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
it('does not create the user', async () => {
|
||||
await expect(createTestUser(name, undefined, undefined, true)).to.be
|
||||
.rejected
|
||||
expect(await getRepository(User).findOneBy({ name })).to.be.null
|
||||
})
|
||||
})
|
||||
const user = await createTestUser(testUser, invite.code)
|
||||
|
||||
expect(await getUserFollowers(user)).to.eql([adminUser])
|
||||
expect(await getUserFollowing(user)).to.eql([adminUser])
|
||||
expect(await getUserFollowers(adminUser)).to.eql([user])
|
||||
expect(await getUserFollowing(adminUser)).to.eql([user])
|
||||
}).timeout(10000)
|
||||
|
||||
it('creates profile when user exists but profile not', async () => {
|
||||
after(async () => {
|
||||
await deleteTestUser(name)
|
||||
})
|
||||
|
||||
const name = 'userWithoutProfile'
|
||||
const user = await createUserWithoutProfile(name)
|
||||
|
||||
await createTestUser(user.name)
|
||||
|
||||
const profile = await getProfile(user)
|
||||
|
||||
expect(profile).to.exist
|
||||
})
|
||||
})
|
||||
|
||||
describe('create a user with pending confirmation', () => {
|
||||
const name = 'pendingUser'
|
||||
let fake: (msg: MailDataRequired) => Promise<boolean>
|
||||
|
||||
beforeEach(() => {
|
||||
fake = sinon.replace(util, 'sendEmail', sinon.fake.resolves(true))
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
sinon.restore()
|
||||
await deleteTestUser(name)
|
||||
})
|
||||
|
||||
it('creates the user with pending status and correct name', async () => {
|
||||
const user = await createTestUser(name, undefined, undefined, true)
|
||||
|
||||
expect(user.status).to.eql(StatusType.Pending)
|
||||
expect(user.name).to.eql(name)
|
||||
})
|
||||
|
||||
it('sends an email to the user', async () => {
|
||||
await createTestUser(name, undefined, undefined, true)
|
||||
|
||||
expect(fake).to.have.been.calledOnce
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user