eletrotupi / tcc/ api/tests/users/avatar.test.tsc901c35af9c84b6a29e5185545ced1129f33b8f4
4.1 KB | 146 lines Raw
1
import { describe, it, expect, afterAll, beforeEach, vi } from 'vitest'
2
import request from 'supertest'
3
import { DeleteObjectCommand } from '@aws-sdk/client-s3'
4
import { createApp } from '@app/createApp'
5
import s3 from '@app/lib/s3'
6
import {
7
  buildPrisma,
8
  cleanupTestDb,
9
  createTestUser,
10
  generateTestToken,
11
  expectPublicUser,
12
} from '../test-helper'
13

14
import { resetAvatarMock, setUploadedFile } from '../mocks/avatar'
15

16
const app = createApp()
17
const db = buildPrisma()
18
const mockedSend = vi.mocked(s3.send)
19

20
afterAll(() => db.$disconnect())
21

22
beforeEach(async () => {
23
  await cleanupTestDb(db)
24

25
  resetAvatarMock()
26
  mockedSend.mockClear()
27
})
28

29
const uploadedFile = {
30
  location: 'https://cdn.example.com/avatars/new.png',
31
  key: 'avatars/new.png',
32
  originalname: 'new.png',
33
  size: 1234,
34
  mimetype: 'image/png',
35
}
36

37
describe('POST /users/me/avatar', () => {
38
  it('stores the uploaded file on the user', async () => {
39
    const user = await createTestUser(db)
40
    const token = generateTestToken(user.id, user.email)
41

42
    setUploadedFile(uploadedFile)
43

44
    const res = await request(app)
45
      .post('/users/me/avatar')
46
      .set('Authorization', `Bearer ${token}`)
47

48
    expect(res.status).toBe(200)
49
    expect(res.body.key).toBe('avatars/new.png')
50
    expect(res.body.user.avatarURL).toBe(uploadedFile.location)
51
    expect(res.body.user.avatarKey).toBe('avatars/new.png')
52
    expectPublicUser(res.body.user)
53

54
    const dbUser = await db.user.findUnique({ where: { id: user.id } })
55

56
    expect(dbUser!.avatarURL).toBe(uploadedFile.location)
57
  })
58

59
  it('deletes the previous object when replacing an avatar', async () => {
60
    const user = await createTestUser(db)
61
    await db.user.update({
62
      where: { id: user.id },
63
      data: {
64
        avatarKey: 'avatars/old.png',
65
        avatarURL: 'https://cdn.example.com/avatars/old.png'
66
      },
67
    })
68

69
    const token = generateTestToken(user.id, user.email)
70
    setUploadedFile(uploadedFile)
71

72
    const res = await request(app)
73
      .post('/users/me/avatar')
74
      .set('Authorization', `Bearer ${token}`)
75

76
    expect(res.status).toBe(200)
77
    expect(mockedSend).toHaveBeenCalledOnce()
78
    expect(mockedSend).toHaveBeenCalledWith(expect.any(DeleteObjectCommand))
79
  })
80

81
  it('returns 400 when no file is present', async () => {
82
    const user = await createTestUser(db)
83
    const token = generateTestToken(user.id, user.email)
84

85
    const res = await request(app)
86
      .post('/users/me/avatar')
87
      .set('Authorization', `Bearer ${token}`)
88

89
    expect(res.status).toBe(400)
90
    expect(mockedSend).not.toHaveBeenCalled()
91
  })
92

93
  it('returns 401 without a token', async () => {
94
    setUploadedFile(uploadedFile)
95

96
    const res = await request(app).post('/users/me/avatar')
97
    expect(res.status).toBe(401)
98
  })
99
})
100

101
describe('DELETE /users/me/avatar', () => {
102
  it('clears the stored avatar and deletes the object', async () => {
103
    const user = await createTestUser(db)
104

105
    await db.user.update({
106
      where: { id: user.id },
107
      data: {
108
        avatarKey: 'avatars/old.png',
109
        avatarURL: 'https://cdn.example.com/avatars/old.png'
110
      },
111
    })
112
    const token = generateTestToken(user.id, user.email)
113

114
    const res = await request(app)
115
      .delete('/users/me/avatar')
116
      .set('Authorization', `Bearer ${token}`)
117

118
    expect(res.status).toBe(200)
119
    expect(res.body.user.avatarKey).toBeNull()
120
    expect(res.body.user.avatarURL).toBeNull()
121
    expectPublicUser(res.body.user)
122
    expect(mockedSend).toHaveBeenCalledOnce()
123

124
    const dbUser = await db.user.findUnique({ where: { id: user.id } })
125

126
    expect(dbUser!.avatarKey).toBeNull()
127
  })
128

129
  it('is a no-op when there is no avatar to remove', async () => {
130
    const user = await createTestUser(db)
131
    const token = generateTestToken(user.id, user.email)
132

133
    const res = await request(app)
134
      .delete('/users/me/avatar')
135
      .set('Authorization', `Bearer ${token}`)
136

137
    expect(res.status).toBe(200)
138
    expect(res.body.user.id).toBe(user.id)
139
    expect(mockedSend).not.toHaveBeenCalled()
140
  })
141

142
  it('returns 401 without a token', async () => {
143
    const res = await request(app).delete('/users/me/avatar')
144
    expect(res.status).toBe(401)
145
  })
146
})