eletrotupi / tcc/ api/tests/jobs/mail.test.tsc901c35af9c84b6a29e5185545ced1129f33b8f4
4.0 KB | 132 lines Raw
1
import { describe, it, expect, afterAll, beforeEach, vi } from 'vitest'
2
import { sendWelcomeEmail } from '@app/services/mail/welcome'
3
import { sendActivateAccountEmail } from '@app/services/mail/sendActivateAccountEmail'
4
import { sendResetPasswordEmail } from '@app/services/mail/sendPasswordReset'
5
import { mailProcessor } from '@app/lib/queue/processors/mail'
6
import { MailJobName } from '@app/lib/queue/types'
7
import { buildPrisma, cleanupTestDb, createTestUser } from '../test-helper'
8

9
// Intercept all Resend calls
10
vi.mock('@app/lib/mail', () => ({
11
  sendEmail: vi.fn().mockResolvedValue({
12
    data: { id: 'fake-email-id' },
13
    error: null
14
  }),
15
}))
16

17
import { sendEmail } from '@app/lib/mail'
18
const mockedSendEmail = vi.mocked(sendEmail)
19

20
const db = buildPrisma()
21

22
afterAll(() => db.$disconnect())
23
beforeEach(async () => {
24
  await cleanupTestDb(db)
25
  mockedSendEmail.mockClear()
26
})
27

28
describe('sendWelcomeEmail', () => {
29
  it('sends to the correct address with the activation code', async () => {
30
    const user = await createTestUser(db, {
31
      email: 'welcome@example.com',
32
      firstName: 'Maria'
33
    })
34

35
    await sendWelcomeEmail(user.id, '123456')
36

37
    expect(mockedSendEmail).toHaveBeenCalledOnce()
38
    expect(mockedSendEmail).toHaveBeenCalledWith(
39
      expect.objectContaining({
40
        to: 'welcome@example.com',
41
        subject: expect.stringContaining('nexo'),
42
        text: expect.stringContaining('Maria'),
43
      })
44
    )
45

46
    // The code itself is in the body so the user knows what to enter
47
    const [call] = mockedSendEmail.mock.calls
48
    expect(call[0].text).toContain('123456')
49
    expect(call[0].text).toContain('expira em cinco minutos')
50
  })
51
})
52

53
describe('sendActivateAccountEmail', () => {
54
  it('sends to the correct address with the activation code', async () => {
55
    const user = await createTestUser(db, {
56
      email: 'activate@example.com',
57
      firstName: 'João'
58
    })
59

60
    await sendActivateAccountEmail(user.id, '654321')
61

62
    expect(mockedSendEmail).toHaveBeenCalledOnce()
63
    expect(mockedSendEmail).toHaveBeenCalledWith(
64
      expect.objectContaining({
65
        to: 'activate@example.com',
66
        text: expect.stringContaining('João'),
67
      })
68
    )
69
    const [call] = mockedSendEmail.mock.calls
70
    expect(call[0].text).toContain('654321')
71
    expect(call[0].text).toContain('expira em cinco minutos')
72
  })
73
})
74

75
describe('sendResetPasswordEmail', () => {
76
  it('sends to the correct address with the reset token', async () => {
77
    const user = await createTestUser(db, {
78
      email: 'reset@example.com',
79
      firstName: 'Ana'
80
    })
81

82
    await sendResetPasswordEmail(user.id, 'token-abc-xyz')
83

84
    expect(mockedSendEmail).toHaveBeenCalledOnce()
85
    expect(mockedSendEmail).toHaveBeenCalledWith(
86
      expect.objectContaining({
87
        to: 'reset@example.com',
88
        subject: expect.stringContaining('nexo'),
89
        text: expect.stringContaining('token-abc-xyz'),
90
      })
91
    )
92
  })
93

94
  it('renders a clickable deep link in the html body', async () => {
95
    const user = await createTestUser(db, {
96
      email: 'reset-html@example.com',
97
      firstName: 'Ana'
98
    })
99

100
    await sendResetPasswordEmail(user.id, 'token-abc-xyz')
101

102
    const [call] = mockedSendEmail.mock.calls
103
    expect(call[0].html).toContain(
104
      'href="orbit://auth/reset-password?token=token-abc-xyz"'
105
    )
106
  })
107
})
108

109
describe('mailProcessor', () => {
110
  it('dispatches a password reset email and awaits it', async () => {
111
    const user = await createTestUser(db, {
112
      email: 'proc@example.com',
113
      firstName: 'Lucas'
114
    })
115

116
    await mailProcessor({
117
      name: MailJobName.PasswordReset,
118
      data: { userId: user.id, token: 'reset-token-123' },
119
    } as any)
120

121
    expect(mockedSendEmail).toHaveBeenCalledOnce()
122
    expect(mockedSendEmail).toHaveBeenCalledWith(
123
      expect.objectContaining({ to: 'proc@example.com' })
124
    )
125
  })
126

127
  it('throws for unknown job names', async () => {
128
    await expect(
129
      mailProcessor({ name: 'mail:unknown', data: {} } as any)
130
    ).rejects.toThrow('Unknown mail job')
131
  })
132
})