eletrotupi / tcc/ api/tests/mood/queries.test.js56ae9d8272c35d408c95fb441f727bf93b0507d3
8.3 KB | 298 lines Raw
1
import test from "ava";
2
import request from "supertest";
3
import { createApp } from "../../src/create-app.js";
4
import { setupTestDb, cleanupTestDb } from "../test-helper.js";
5

6
let app;
7
let db;
8
let userId;
9
let moodIds = [];
10

11
test.before(() => {
12
  db = setupTestDb();
13
  app = createApp(db);
14
});
15

16
test.beforeEach(async () => {
17
  cleanupTestDb();
18
  moodIds = [];
19

20
  // Create a test user with unique email
21
  const uniqueEmail = `mood_${Date.now()}_${Math.random()}@example.com`;
22
  const userRes = await request(app)
23
    .post("/users")
24
    .send({
25
      email: uniqueEmail,
26
      password: "senha123",
27
      first_name: "Mood",
28
      last_name: "Tester"
29
    });
30

31
  if (userRes.status !== 201) {
32
    throw new Error(`Failed to create test user: ${JSON.stringify(userRes.body)}`);
33
  }
34

35
  userId = userRes.body.id;
36

37
  // Create multiple moods for testing
38
  const dates = [
39
    new Date('2024-01-15T10:00:00Z'),
40
    new Date('2024-01-20T14:30:00Z'),
41
    new Date('2024-02-01T08:00:00Z'),
42
    new Date('2024-02-15T16:45:00Z'),
43
    new Date('2024-03-01T12:00:00Z')
44
  ];
45

46
  for (let i = 0; i < dates.length; i++) {
47
    const moodRes = await request(app)
48
      .post("/mood")
49
      .send({
50
        user_id: userId,
51
        rating: 5 + i,
52
        stress_level: 3 + i,
53
        anxiety_level: 2 + i,
54
        energy_level: 6 - i,
55
        title: `Mood ${i + 1}`,
56
        recorded_at: dates[i].toISOString(),
57
        mood_components: i % 2 === 0 ? [
58
          { emotion: "joy", intensity: 5 + i },
59
          { emotion: "trust", intensity: 4 + i }
60
        ] : []
61
      });
62
    moodIds.push(moodRes.body.id);
63
  }
64
});
65

66
test.serial("Obter mood específico por ID", async (t) => {
67
  const res = await request(app).get(`/mood/${moodIds[0]}`);
68

69
  t.is(res.status, 200);
70
  t.is(Number(res.body.id), Number(moodIds[0]));
71
  t.is(Number(res.body.user_id), Number(userId));
72
  t.is(res.body.title, "Mood 1");
73
  t.truthy(res.body.first_name);
74
  t.truthy(res.body.last_name);
75
  t.true(Array.isArray(res.body.mood_components));
76
});
77

78
test.serial("Mood deve incluir componentes emocionais", async (t) => {
79
  const res = await request(app).get(`/mood/${moodIds[0]}`);
80

81
  t.is(res.status, 200);
82
  t.is(res.body.mood_components.length, 2);
83

84
  const emotions = res.body.mood_components.map(c => c.emotion);
85
  t.true(emotions.includes('joy'));
86
  t.true(emotions.includes('trust'));
87
});
88

89
test.serial("Mood deve incluir estatísticas emocionais quando houver componentes", async (t) => {
90
  const res = await request(app).get(`/mood/${moodIds[0]}`);
91

92
  t.is(res.status, 200);
93
  t.truthy(res.body.emotion_stats);
94
  t.truthy(res.body.emotion_stats.dominant);
95
  t.truthy(res.body.emotion_stats.average);
96
  t.truthy(res.body.emotion_stats.breakdown);
97
});
98

99
test.serial("Falha ao obter mood inexistente", async (t) => {
100
  const res = await request(app).get("/mood/99999");
101

102
  t.is(res.status, 404);
103
  t.is(res.body.error, "Humor não encontrado");
104
});
105

106
test.serial("Obter todos os moods de um usuário", async (t) => {
107
  const res = await request(app).get(`/mood/user/${userId}`);
108

109
  t.is(res.status, 200);
110
  t.truthy(res.body.moods);
111
  t.is(res.body.moods.length, 5);
112
  t.truthy(res.body.pagination);
113
  t.is(res.body.pagination.total, 5);
114
});
115

116
test.serial("Moods devem estar ordenados por data (mais recente primeiro)", async (t) => {
117
  const res = await request(app).get(`/mood/user/${userId}`);
118

119
  t.is(res.status, 200);
120

121
  const dates = res.body.moods.map(m => new Date(m.recorded_at));
122
  for (let i = 1; i < dates.length; i++) {
123
    t.true(dates[i - 1] >= dates[i]);
124
  }
125
});
126

127
test.serial("Filtrar registros de humor por intervalo de datas", async (t) => {
128
  const res = await request(app).get(`/mood/user/${userId}`)
129
    .query({
130
      start_date: '2024-01-01',
131
      end_date: '2024-01-31'
132
    });
133

134
  t.is(res.status, 200);
135
  t.is(res.body.moods.length, 2); // Only January moods
136
});
137

138
test.serial("Filtrar registros de humor apenas por data de início", async (t) => {
139
  const res = await request(app).get(`/mood/user/${userId}`)
140
    .query({
141
      start_date: '2024-02-01'
142
    });
143

144
  t.is(res.status, 200);
145
  t.is(res.body.moods.length, 3); // Feb and March moods
146
});
147

148
test.serial("Filtrar registros de humor apenas por data de fim", async (t) => {
149
  const res = await request(app).get(`/mood/user/${userId}`)
150
    .query({
151
      end_date: '2024-01-31'
152
    });
153

154
  t.is(res.status, 200);
155
  t.is(res.body.moods.length, 2); // Only January moods
156
});
157

158
test.serial("Paginação de moods", async (t) => {
159
  const res = await request(app).get(`/mood/user/${userId}`)
160
    .query({
161
      page: 2,
162
      limit: 2
163
    });
164

165
  t.is(res.status, 200);
166
  t.is(res.body.moods.length, 2);
167
  t.is(res.body.pagination.page, 2);
168
  t.is(res.body.pagination.limit, 2);
169
  t.is(res.body.pagination.total_pages, 3);
170
});
171

172
test.serial("Paginação com limite máximo de 100", async (t) => {
173
  const res = await request(app).get(`/mood/user/${userId}`)
174
    .query({
175
      limit: 200
176
    });
177

178
  t.is(res.status, 200);
179
  t.is(res.body.pagination.limit, 100); // Should be capped at 100
180
});
181

182
test.serial("Falha ao filtrar com intervalo de datas inválido", async (t) => {
183
  const res = await request(app).get(`/mood/user/${userId}`)
184
    .query({
185
      start_date: '2024-02-01',
186
      end_date: '2024-01-01' // End before start
187
    });
188

189
  t.is(res.status, 400);
190
  t.is(res.body.error, "Intervalo de datas inválido");
191
});
192

193
test.serial("Falha ao filtrar com data de início inválida", async (t) => {
194
  const res = await request(app).get(`/mood/user/${userId}`)
195
    .query({
196
      start_date: 'data-invalida'
197
    });
198

199
  t.is(res.status, 400);
200
  t.is(res.body.error, "Data de início inválida");
201
});
202

203
test.serial("Falha ao filtrar com data de fim inválida", async (t) => {
204
  const res = await request(app).get(`/mood/user/${userId}`)
205
    .query({
206
      end_date: 'data-invalida'
207
    });
208

209
  t.is(res.status, 400);
210
  t.is(res.body.error, "Data de fim inválida");
211
});
212

213
test.serial("Obter estatísticas de mood do usuário", async (t) => {
214
  const res = await request(app).get(`/mood/user/${userId}/stats`);
215

216
  t.is(res.status, 200);
217
  t.truthy(res.body.overall);
218
  t.is(res.body.overall.total_entries, 5);
219
  t.truthy(res.body.overall.avg_rating);
220
  t.truthy(res.body.overall.avg_stress);
221
  t.truthy(res.body.overall.avg_anxiety);
222
  t.truthy(res.body.overall.avg_energy);
223
  t.truthy(res.body.emotions);
224
  t.truthy(res.body.trends);
225
});
226

227
test.serial("Estatísticas devem incluir frequência de emoções", async (t) => {
228
  const res = await request(app).get(`/mood/user/${userId}/stats`);
229

230
  t.is(res.status, 200);
231
  t.true(Array.isArray(res.body.emotions));
232

233
  // We created 3 moods with components
234
  const joyStats = res.body.emotions.find(e => e.emotion === 'joy');
235
  t.truthy(joyStats);
236
  t.is(joyStats.frequency, 3);
237
});
238

239
test.serial("Estatísticas com filtro de data", async (t) => {
240
  const res = await request(app).get(`/mood/user/${userId}/stats`)
241
    .query({
242
      start_date: '2024-01-01',
243
      end_date: '2024-01-31'
244
    });
245

246
  t.is(res.status, 200);
247
  t.is(res.body.overall.total_entries, 2); // Only January
248
  t.is(res.body.date_range.start, '2024-01-01');
249
  t.is(res.body.date_range.end, '2024-01-31');
250
});
251

252
test.serial("Estatísticas devem incluir tendências por dia da semana", async (t) => {
253
  const res = await request(app).get(`/mood/user/${userId}/stats`);
254

255
  t.is(res.status, 200);
256
  t.true(Array.isArray(res.body.trends.by_day_of_week));
257

258
  const hasDay = res.body.trends.by_day_of_week.some(d =>
259
    ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'].includes(d.day_of_week)
260
  );
261
  t.true(hasDay);
262
});
263

264
test.serial("Usuário sem moods deve retornar lista vazia", async (t) => {
265
  // Create another user without moods
266
  const newUserRes = await request(app)
267
    .post("/users")
268
    .send({
269
      email: "nomood@example.com",
270
      password: "senha123",
271
      first_name: "No",
272
      last_name: "Mood"
273
    });
274

275
  const res = await request(app).get(`/mood/user/${newUserRes.body.id}`);
276

277
  t.is(res.status, 200);
278
  t.is(res.body.moods.length, 0);
279
  t.is(res.body.pagination.total, 0);
280
});
281

282
test.serial("Estatísticas de usuário sem moods", async (t) => {
283
  // Create another user without moods
284
  const newUserRes = await request(app)
285
    .post("/users")
286
    .send({
287
      email: "nostats@example.com",
288
      password: "senha123",
289
      first_name: "No",
290
      last_name: "Stats"
291
    });
292

293
  const res = await request(app).get(`/mood/user/${newUserRes.body.id}/stats`);
294

295
  t.is(res.status, 200);
296
  t.is(res.body.overall.total_entries, 0);
297
  t.is(res.body.emotions.length, 0);
298
});