eletrotupi / tcc/ api/tests/auth/activate.test.ts723aa5b7572d23224264ea878b70e7a915d2c5c4
5.0 KB | 167 lines Raw
1
import { describe, it, expect, afterAll, beforeEach } from 'vitest'
2
import request from 'supertest'
3
import { createApp } from '@app/createApp'
4
import {
5
  buildPrisma,
6
  cleanupTestDb,
7
  createTestUser,
8
  generateTestToken,
9
} from '../test-helper'
10

11
const app = createApp()
12
const db = buildPrisma()
13

14
afterAll(() => db.$disconnect())
15
beforeEach(() => cleanupTestDb(db))
16

17
async function seedActivationCode(
18
  userId: number,
19
  code = '123456',
20
  expiresInMs = 5 * 60 * 1000
21
) {
22
  return db.user.update({
23
    where: { id: userId },
24
    data: {
25
      activationCode: code,
26
      activationCodeExpiresAt: new Date(Date.now() + expiresInMs),
27
    },
28
  })
29
}
30

31
describe('POST /auth/activate', () => {
32
  it('activates the user and clears the code', async () => {
33
    const user = await createTestUser(db, { email: 'activate@example.com' })
34
    await seedActivationCode(user.id)
35

36
    const res = await request(app)
37
      .post('/auth/activate')
38
      .send({ code: '123456' })
39

40
    expect(res.status).toBe(200)
41
    expect(res.body.user.active).toBe(true)
42
    expect(res.body.user.activationCode).toBeNull()
43

44
    const dbUser = await db.user.findUnique({ where: { id: user.id } })
45
    expect(dbUser!.active).toBe(true)
46
    expect(dbUser!.activationCode).toBeNull()
47
    expect(dbUser!.activationCodeExpiresAt).toBeNull()
48
  })
49

50
  it('activates an account whose code begins with zero', async () => {
51
    const user = await createTestUser(db, { email: 'leading-zero@example.com' })
52
    await seedActivationCode(user.id, '012345')
53

54
    const res = await request(app)
55
      .post('/auth/activate')
56
      .send({ code: '012345' })
57

58
    expect(res.status).toBe(200)
59
    expect(res.body.user.active).toBe(true)
60

61
    const dbUser = await db.user.findUnique({ where: { id: user.id } })
62
    expect(dbUser!.active).toBe(true)
63
    expect(dbUser!.activationCode).toBeNull()
64
  })
65

66
  it('rejects a correctly issued code past its expiry', async () => {
67
    const user = await createTestUser(db, { email: 'expired@example.com' })
68
    await seedActivationCode(user.id, '123456', -1000)
69

70
    const res = await request(app)
71
      .post('/auth/activate')
72
      .send({ code: '123456' })
73

74
    expect(res.status).toBe(422)
75
    expect(res.body.error).toBeTruthy()
76
  })
77

78
  it('rejects a code recorded without an expiry', async () => {
79
    const user = await createTestUser(db, { email: 'no-expiry@example.com' })
80
    await db.user.update({
81
      where: { id: user.id },
82
      data: { activationCode: '123456', activationCodeExpiresAt: null },
83
    })
84

85
    const res = await request(app)
86
      .post('/auth/activate')
87
      .send({ code: '123456' })
88

89
    expect(res.status).toBe(422)
90
  })
91

92
  it('returns 422 for a well-formed but unknown code', async () => {
93
    await createTestUser(db, { email: 'activate@example.com' })
94

95
    const res = await request(app)
96
      .post('/auth/activate')
97
      .send({ code: '999999' })
98

99
    expect(res.status).toBe(422)
100
    expect(res.body.error).toBeTruthy()
101
  })
102

103
  it('cannot tell an expired code from an unknown one', async () => {
104
    const user = await createTestUser(db, { email: 'indistinct@example.com' })
105
    await seedActivationCode(user.id, '123456', -1000)
106

107
    const expired = await request(app)
108
      .post('/auth/activate')
109
      .send({ code: '123456' })
110

111
    const unknown = await request(app)
112
      .post('/auth/activate')
113
      .send({ code: '654321' })
114

115
    expect(expired.status).toBe(unknown.status)
116
    expect(expired.body).toEqual(unknown.body)
117
  })
118

119
  it('leaves the stored code in place when an expired code is rejected', async () => {
120
    const user = await createTestUser(db, { email: 'no-reissue@example.com' })
121
    await seedActivationCode(user.id, '123456', -1000)
122

123
    await request(app).post('/auth/activate').send({ code: '123456' })
124

125
    const dbUser = await db.user.findUnique({ where: { id: user.id } })
126
    expect(dbUser!.active).toBe(false)
127
    expect(dbUser!.activationCode).toBe('123456')
128
  })
129

130
  it.each([
131
    ['too short', '12345'],
132
    ['too long', '1234567'],
133
    ['non-digit', '12a456'],
134
    ['a number', 123456],
135
  ])('rejects a code that is %s as malformed', async (_shape, code) => {
136
    await createTestUser(db, { email: 'activate@example.com' })
137

138
    const res = await request(app)
139
      .post('/auth/activate')
140
      .send({ code })
141

142
    expect(res.status).toBe(400)
143
    expect(res.body.fields.code).toBeTruthy()
144
  })
145
})
146

147
describe('POST /auth/resend_code', () => {
148
  it('issues a fresh activation code for the authenticated user', async () => {
149
    const user = await createTestUser(db, { email: 'resend@example.com' })
150
    const token = generateTestToken(user.id, user.email)
151

152
    const res = await request(app)
153
      .post('/auth/resend_code')
154
      .set('Authorization', `Bearer ${token}`)
155

156
    expect(res.status).toBe(200)
157

158
    const dbUser = await db.user.findUnique({ where: { id: user.id } })
159
    expect(dbUser!.activationCode).toMatch(/^\d{6}$/)
160
    expect(dbUser!.activationCodeExpiresAt).not.toBeNull()
161
  })
162

163
  it('returns 401 without a token', async () => {
164
    const res = await request(app).post('/auth/resend_code')
165
    expect(res.status).toBe(401)
166
  })
167
})