eletrotupi / tcc/ commit / 5bd46fe

api: add mail tests

Pedro Lucas Porcellis porcellis@eletrotupi.com · 4 months ago 5bd46fe1f249c194dc947ce12c0cd30f7bbf94ca Browse files
Parents 2b1f047
Changed files
1
Additions
+116
Deletions
0
/dev/null → api/tests/jobs/mail.test.ts
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('orbit'),
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 +
  })
50 +
})
51 +

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

59 +
    await sendActivateAccountEmail(user.id, '654321')
60 +

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

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

80 +
    await sendResetPasswordEmail(user.id, 'token-abc-xyz')
81 +

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

93 +
describe('mailProcessor', () => {
94 +
  it('dispatches a password reset email and awaits it', async () => {
95 +
    const user = await createTestUser(db, {
96 +
      email: 'proc@example.com',
97 +
      firstName: 'Lucas'
98 +
    })
99 +

100 +
    await mailProcessor({
101 +
      name: MailJobName.PasswordReset,
102 +
      data: { userId: user.id, token: 'reset-token-123' },
103 +
    } as any)
104 +

105 +
    expect(mockedSendEmail).toHaveBeenCalledOnce()
106 +
    expect(mockedSendEmail).toHaveBeenCalledWith(
107 +
      expect.objectContaining({ to: 'proc@example.com' })
108 +
    )
109 +
  })
110 +

111 +
  it('throws for unknown job names', async () => {
112 +
    await expect(
113 +
      mailProcessor({ name: 'mail:unknown', data: {} } as any)
114 +
    ).rejects.toThrow('Unknown mail job')
115 +
  })
116 +
})