api: introduce tests for care actions and medicine regimens
Pedro Lucas Porcellis porcellis@eletrotupi.com · 4 months ago
1af3a2380bb059a294d94614698c642eb65b1315 Browse filesParents
d5fb879Changed files
3
Additions
+456
Deletions
0
/dev/null → api/tests/care-actions/create.test.ts
1 +
import { describe, it, expect, afterAll, beforeEach } from 'vitest'
2 +
import request from 'supertest'
3 +
import { createApp } from '@app/createApp'
4 +
import { buildPrisma, cleanupTestDb, createTestUser, generateTestToken } from '../test-helper'
5 +
6 +
const app = createApp()
7 +
const db = buildPrisma()
8 +
9 +
const moment = new Date().toISOString()
10 +
11 +
afterAll(() => db.$disconnect())
12 +
beforeEach(() => cleanupTestDb(db))
13 +
14 +
describe('POST /care-actions', () => {
15 +
it('creates an ACTIVITY care action', async () => {
16 +
const user = await createTestUser(db)
17 +
const token = generateTestToken(user.id, user.email)
18 +
19 +
const res = await request(app)
20 +
.post('/care-actions')
21 +
.set('Authorization', `Bearer ${token}`)
22 +
.send({
23 +
careAction: {
24 +
type: 'ACTIVITY',
25 +
moment,
26 +
activity: { type: 'WALK', duration: 30 },
27 +
},
28 +
})
29 +
30 +
expect(res.status).toBe(201)
31 +
expect(res.body.careAction.type).toBe('ACTIVITY')
32 +
expect(res.body.careAction.activity.type).toBe('WALK')
33 +
expect(res.body.careAction.activity.duration).toBe(30)
34 +
35 +
const dbRecord = await db.careAction.findFirst({ where: { userId: user.id } })
36 +
expect(dbRecord).not.toBeNull()
37 +
})
38 +
39 +
it('creates an APPOINTMENT care action', async () => {
40 +
const user = await createTestUser(db)
41 +
const token = generateTestToken(user.id, user.email)
42 +
43 +
const res = await request(app)
44 +
.post('/care-actions')
45 +
.set('Authorization', `Bearer ${token}`)
46 +
.send({
47 +
careAction: {
48 +
type: 'APPOINTMENT',
49 +
moment,
50 +
appointment: { type: 'ANALYST', duration: 50, note: 'Primeira sessão' },
51 +
},
52 +
})
53 +
54 +
expect(res.status).toBe(201)
55 +
expect(res.body.careAction.type).toBe('APPOINTMENT')
56 +
expect(res.body.careAction.appointment.type).toBe('ANALYST')
57 +
expect(res.body.careAction.appointment.note).toBe('Primeira sessão')
58 +
})
59 +
60 +
it('creates a MEDICINE care action linked to an existing regimen', async () => {
61 +
const user = await createTestUser(db)
62 +
const token = generateTestToken(user.id, user.email)
63 +
64 +
const regimen = await db.medicineRegimen.create({
65 +
data: {
66 +
userId: user.id,
67 +
name: 'Sertralina',
68 +
dosage: '50mg',
69 +
periodicity: 'DAILY',
70 +
scheduledAt: [],
71 +
},
72 +
})
73 +
74 +
const res = await request(app)
75 +
.post('/care-actions')
76 +
.set('Authorization', `Bearer ${token}`)
77 +
.send({
78 +
careAction: {
79 +
type: 'MEDICINE',
80 +
moment,
81 +
regimenId: regimen.id,
82 +
},
83 +
})
84 +
85 +
expect(res.status).toBe(201)
86 +
expect(res.body.careAction.type).toBe('MEDICINE')
87 +
expect(res.body.careAction.medicineLog.regimen.id).toBe(regimen.id)
88 +
})
89 +
90 +
it('creates a MEDICINE care action with inline medicine, creating a new regimen', async () => {
91 +
const user = await createTestUser(db)
92 +
const token = generateTestToken(user.id, user.email)
93 +
94 +
const res = await request(app)
95 +
.post('/care-actions')
96 +
.set('Authorization', `Bearer ${token}`)
97 +
.send({
98 +
careAction: {
99 +
type: 'MEDICINE',
100 +
moment,
101 +
medicine: {
102 +
name: 'Melatonina',
103 +
dosage: '5mg',
104 +
periodicity: 'DAILY',
105 +
scheduledAt: ['22:00'],
106 +
},
107 +
},
108 +
})
109 +
110 +
expect(res.status).toBe(201)
111 +
expect(res.body.careAction.medicineLog.regimen.name).toBe('Melatonina')
112 +
113 +
const regimenCount = await db.medicineRegimen.count({ where: { userId: user.id } })
114 +
expect(regimenCount).toBe(1)
115 +
})
116 +
117 +
it('returns 401 without a token', async () => {
118 +
const res = await request(app)
119 +
.post('/care-actions')
120 +
.send({ careAction: { type: 'ACTIVITY', moment, activity: { type: 'WALK' } } })
121 +
122 +
expect(res.status).toBe(401)
123 +
})
124 +
})
/dev/null → api/tests/care-actions/list.test.ts
1 +
import { describe, it, expect, afterAll, beforeEach } from 'vitest'
2 +
import request from 'supertest'
3 +
import { createApp } from '@app/createApp'
4 +
import { buildPrisma, cleanupTestDb, createTestUser, generateTestToken } from '../test-helper'
5 +
6 +
const app = createApp()
7 +
const db = buildPrisma()
8 +
9 +
afterAll(() => db.$disconnect())
10 +
beforeEach(() => cleanupTestDb(db))
11 +
12 +
async function seedActivity(userId: number, overrides: { moment?: Date } = {}) {
13 +
return db.careAction.create({
14 +
data: {
15 +
userId,
16 +
type: 'ACTIVITY',
17 +
moment: overrides.moment ?? new Date(),
18 +
activity: { create: { type: 'WALK' } },
19 +
},
20 +
})
21 +
}
22 +
23 +
describe('GET /care-actions', () => {
24 +
it('returns an empty list when no actions exist', async () => {
25 +
const user = await createTestUser(db)
26 +
const token = generateTestToken(user.id, user.email)
27 +
28 +
const res = await request(app)
29 +
.get('/care-actions')
30 +
.set('Authorization', `Bearer ${token}`)
31 +
32 +
expect(res.status).toBe(200)
33 +
expect(res.body.entries).toEqual([])
34 +
expect(res.body.total).toBe(0)
35 +
})
36 +
37 +
it('returns only the authenticated user\'s actions', async () => {
38 +
const user = await createTestUser(db)
39 +
const other = await createTestUser(db, { email: 'other@example.com' })
40 +
const token = generateTestToken(user.id, user.email)
41 +
42 +
await seedActivity(user.id)
43 +
await seedActivity(other.id)
44 +
45 +
const res = await request(app)
46 +
.get('/care-actions')
47 +
.set('Authorization', `Bearer ${token}`)
48 +
49 +
expect(res.status).toBe(200)
50 +
expect(res.body.entries).toHaveLength(1)
51 +
expect(res.body.entries[0].userId).toBe(user.id)
52 +
})
53 +
54 +
it('filters by type', async () => {
55 +
const user = await createTestUser(db)
56 +
const token = generateTestToken(user.id, user.email)
57 +
58 +
await seedActivity(user.id)
59 +
await db.careAction.create({
60 +
data: {
61 +
userId: user.id,
62 +
type: 'APPOINTMENT',
63 +
moment: new Date(),
64 +
appointment: { create: { type: 'GP', duration: 30 } },
65 +
},
66 +
})
67 +
68 +
const res = await request(app)
69 +
.get('/care-actions?type=ACTIVITY')
70 +
.set('Authorization', `Bearer ${token}`)
71 +
72 +
expect(res.status).toBe(200)
73 +
expect(res.body.entries).toHaveLength(1)
74 +
expect(res.body.entries[0].type).toBe('ACTIVITY')
75 +
})
76 +
})
77 +
78 +
describe('GET /care-actions/:id', () => {
79 +
it('returns a single care action', async () => {
80 +
const user = await createTestUser(db)
81 +
const token = generateTestToken(user.id, user.email)
82 +
const action = await seedActivity(user.id)
83 +
84 +
const res = await request(app)
85 +
.get(`/care-actions/${action.id}`)
86 +
.set('Authorization', `Bearer ${token}`)
87 +
88 +
expect(res.status).toBe(200)
89 +
expect(res.body.id).toBe(action.id)
90 +
})
91 +
})
92 +
93 +
describe('PATCH /care-actions/:id', () => {
94 +
it('links a care action to a mood', async () => {
95 +
const user = await createTestUser(db)
96 +
const token = generateTestToken(user.id, user.email)
97 +
const action = await seedActivity(user.id)
98 +
99 +
const mood = await db.mood.create({
100 +
data: {
101 +
userId: user.id,
102 +
selectedMood: 'GOOD',
103 +
anxietyLevel: 1,
104 +
stressLevel: 1,
105 +
energyLevel: 8,
106 +
moment: new Date(),
107 +
moodComponents: { create: [{ component: 'JOY', intensity: 'LIGHT' }] },
108 +
},
109 +
})
110 +
111 +
const res = await request(app)
112 +
.patch(`/care-actions/${action.id}`)
113 +
.set('Authorization', `Bearer ${token}`)
114 +
.send({ careAction: { moodId: mood.id } })
115 +
116 +
expect(res.status).toBe(200)
117 +
expect(res.body.moodId).toBe(mood.id)
118 +
})
119 +
})
120 +
121 +
describe('DELETE /care-actions/:id', () => {
122 +
it('deletes a care action', async () => {
123 +
const user = await createTestUser(db)
124 +
const token = generateTestToken(user.id, user.email)
125 +
const action = await seedActivity(user.id)
126 +
127 +
const res = await request(app)
128 +
.delete(`/care-actions/${action.id}`)
129 +
.set('Authorization', `Bearer ${token}`)
130 +
131 +
expect(res.status).toBe(200)
132 +
133 +
const dbRecord = await db.careAction.findUnique({ where: { id: action.id } })
134 +
expect(dbRecord).toBeNull()
135 +
})
136 +
})
/dev/null → api/tests/medicine-regimens/crud.test.ts
1 +
import { describe, it, expect, afterAll, beforeEach } from 'vitest'
2 +
import request from 'supertest'
3 +
import { createApp } from '@app/createApp'
4 +
import { buildPrisma, cleanupTestDb, createTestUser, generateTestToken } from '../test-helper'
5 +
6 +
const app = createApp()
7 +
const db = buildPrisma()
8 +
9 +
afterAll(() => db.$disconnect())
10 +
beforeEach(() => cleanupTestDb(db))
11 +
12 +
async function seedRegimen(
13 +
userId: number,
14 +
overrides: { name?: string; active?: boolean } = {}
15 +
) {
16 +
return db.medicineRegimen.create({
17 +
data: {
18 +
userId,
19 +
name: overrides.name ?? 'Sertralina',
20 +
dosage: '50mg',
21 +
periodicity: 'DAILY',
22 +
scheduledAt: [],
23 +
active: overrides.active ?? true,
24 +
},
25 +
})
26 +
}
27 +
28 +
describe('POST /medicine-regimens', () => {
29 +
it('creates a regimen and returns it', async () => {
30 +
const user = await createTestUser(db)
31 +
const token = generateTestToken(user.id, user.email)
32 +
33 +
const res = await request(app)
34 +
.post('/medicine-regimens')
35 +
.set('Authorization', `Bearer ${token}`)
36 +
.send({
37 +
regimen: {
38 +
name: 'Clonazepam',
39 +
dosage: '0.5mg',
40 +
periodicity: 'DAILY',
41 +
scheduledAt: ['08:00', '20:00'],
42 +
},
43 +
})
44 +
45 +
expect(res.status).toBe(201)
46 +
expect(res.body.regimen.name).toBe('Clonazepam')
47 +
expect(res.body.regimen.active).toBe(true)
48 +
expect(res.body.regimen.scheduledAt).toEqual(['08:00', '20:00'])
49 +
50 +
const dbRecord = await db.medicineRegimen.findFirst({
51 +
where: { userId: user.id }
52 +
})
53 +
54 +
expect(dbRecord).not.toBeNull()
55 +
})
56 +
57 +
it('returns 400 for missing required fields', async () => {
58 +
const user = await createTestUser(db)
59 +
const token = generateTestToken(user.id, user.email)
60 +
61 +
const res = await request(app)
62 +
.post('/medicine-regimens')
63 +
.set('Authorization', `Bearer ${token}`)
64 +
.send({ regimen: { name: 'X' } })
65 +
66 +
expect(res.status).toBe(400)
67 +
})
68 +
})
69 +
70 +
describe('GET /medicine-regimens', () => {
71 +
it('returns all regimens for the user', async () => {
72 +
const user = await createTestUser(db)
73 +
const other = await createTestUser(db, { email: 'other@example.com' })
74 +
const token = generateTestToken(user.id, user.email)
75 +
76 +
await seedRegimen(user.id, { name: 'Sertralina' })
77 +
await seedRegimen(user.id, { name: 'Ritalina' })
78 +
await seedRegimen(other.id, { name: 'OutroMed' })
79 +
80 +
const res = await request(app)
81 +
.get('/medicine-regimens')
82 +
.set('Authorization', `Bearer ${token}`)
83 +
84 +
expect(res.status).toBe(200)
85 +
expect(res.body.regimens).toHaveLength(2)
86 +
expect(res.body.regimens.every((r: any) => r.userId === user.id)).toBe(true)
87 +
})
88 +
})
89 +
90 +
describe('GET /medicine-regimens/:id', () => {
91 +
it('returns a single regimen', async () => {
92 +
const user = await createTestUser(db)
93 +
const token = generateTestToken(user.id, user.email)
94 +
const regimen = await seedRegimen(user.id)
95 +
96 +
const res = await request(app)
97 +
.get(`/medicine-regimens/${regimen.id}`)
98 +
.set('Authorization', `Bearer ${token}`)
99 +
100 +
expect(res.status).toBe(200)
101 +
expect(res.body.regimen.id).toBe(regimen.id)
102 +
expect(res.body.regimen.name).toBe('Sertralina')
103 +
})
104 +
105 +
it('returns 404 for a regimen belonging to another user', async () => {
106 +
const user = await createTestUser(db)
107 +
const other = await createTestUser(db, { email: 'other@example.com' })
108 +
const token = generateTestToken(user.id, user.email)
109 +
const regimen = await seedRegimen(other.id)
110 +
111 +
const res = await request(app)
112 +
.get(`/medicine-regimens/${regimen.id}`)
113 +
.set('Authorization', `Bearer ${token}`)
114 +
115 +
expect(res.status).toBe(404)
116 +
})
117 +
})
118 +
119 +
describe('PATCH /medicine-regimens/:id', () => {
120 +
it('updates regimen fields', async () => {
121 +
const user = await createTestUser(db)
122 +
const token = generateTestToken(user.id, user.email)
123 +
const regimen = await seedRegimen(user.id)
124 +
125 +
const res = await request(app)
126 +
.patch(`/medicine-regimens/${regimen.id}`)
127 +
.set('Authorization', `Bearer ${token}`)
128 +
.send({ regimen: { dosage: '100mg', scheduledAt: ['09:00'] } })
129 +
130 +
expect(res.status).toBe(200)
131 +
expect(res.body.regimen.dosage).toBe('100mg')
132 +
expect(res.body.regimen.scheduledAt).toEqual(['09:00'])
133 +
})
134 +
})
135 +
136 +
describe('PATCH /medicine-regimens/:id/active', () => {
137 +
it('deactivates a regimen', async () => {
138 +
const user = await createTestUser(db)
139 +
const token = generateTestToken(user.id, user.email)
140 +
const regimen = await seedRegimen(user.id, { active: true })
141 +
142 +
const res = await request(app)
143 +
.patch(`/medicine-regimens/${regimen.id}/active`)
144 +
.set('Authorization', `Bearer ${token}`)
145 +
.send({ active: false })
146 +
147 +
expect(res.status).toBe(200)
148 +
expect(res.body.regimen.active).toBe(false)
149 +
150 +
const dbRecord = await db.medicineRegimen.findUnique({
151 +
where: { id: regimen.id }
152 +
})
153 +
154 +
expect(dbRecord!.active).toBe(false)
155 +
})
156 +
})
157 +
158 +
describe('DELETE /medicine-regimens/:id', () => {
159 +
it('deactivates (soft-deletes) the regimen', async () => {
160 +
const user = await createTestUser(db)
161 +
const token = generateTestToken(user.id, user.email)
162 +
const regimen = await seedRegimen(user.id, { active: true })
163 +
164 +
const res = await request(app)
165 +
.delete(`/medicine-regimens/${regimen.id}`)
166 +
.set('Authorization', `Bearer ${token}`)
167 +
168 +
expect(res.status).toBe(200)
169 +
170 +
const dbRecord = await db.medicineRegimen.findUnique({
171 +
where: { id: regimen.id }
172 +
})
173 +
174 +
expect(dbRecord).not.toBeNull()
175 +
expect(dbRecord!.active).toBe(false)
176 +
})
177 +
})
178 +
179 +
describe('GET /medicine-regimens/today', () => {
180 +
it('returns active regimens with their logs', async () => {
181 +
const user = await createTestUser(db)
182 +
const token = generateTestToken(user.id, user.email)
183 +
184 +
await seedRegimen(user.id, { name: 'Melatonina', active: true })
185 +
await seedRegimen(user.id, { name: 'Inativa', active: false })
186 +
187 +
const res = await request(app)
188 +
.get('/medicine-regimens/today')
189 +
.set('Authorization', `Bearer ${token}`)
190 +
191 +
expect(res.status).toBe(200)
192 +
expect(res.body.regimens).toHaveLength(1)
193 +
expect(res.body.regimens[0].regimen.name).toBe('Melatonina')
194 +
expect(res.body.regimens[0].logs).toBeInstanceOf(Array)
195 +
})
196 +
})