mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-10-16 07:29:52 +08:00
test(api): harden DELETE /users/:userId coverage (#69461)
Co-authored-by: sembauke <sembauke@users.noreply.github.com>
This commit is contained in:
@@ -754,10 +754,11 @@ describe('userRoutes', () => {
|
||||
|
||||
test("only deletes the logged in user's data", async () => {
|
||||
const initialCount = await fastifyTestInstance.prisma.user.count();
|
||||
const otherEmail = 'an.random@user';
|
||||
await fastifyTestInstance.prisma.user.create({
|
||||
data: {
|
||||
...testUserData,
|
||||
email: 'an.random@user'
|
||||
email: otherEmail
|
||||
}
|
||||
});
|
||||
expect(await fastifyTestInstance.prisma.user.count()).toBe(
|
||||
@@ -768,6 +769,29 @@ describe('userRoutes', () => {
|
||||
|
||||
const userCount = await fastifyTestInstance.prisma.user.count();
|
||||
expect(userCount).toBe(initialCount);
|
||||
const remaining = await fastifyTestInstance.prisma.user.findFirst({
|
||||
where: { email: otherEmail }
|
||||
});
|
||||
expect(remaining).not.toBeNull();
|
||||
});
|
||||
|
||||
test('handles concurrent requests to delete the same user', async () => {
|
||||
const deletePromises = Array.from({ length: 2 }, () =>
|
||||
superDelete(`/users/${defaultUserId}`)
|
||||
);
|
||||
|
||||
const responses = await Promise.all(deletePromises);
|
||||
|
||||
const userCount = await fastifyTestInstance.prisma.user.count({
|
||||
where: { email: testUserData.email }
|
||||
});
|
||||
// Both requests race: one deletes the user and returns 204. The other
|
||||
// gets a 401 if the auth middleware queries the DB after the delete, or
|
||||
// a 404 if it clears auth but finds no user left to delete.
|
||||
responses.forEach(response => {
|
||||
expect([204, 401, 404]).toContain(response.status);
|
||||
});
|
||||
expect(userCount).toBe(0);
|
||||
});
|
||||
|
||||
test('logs if it is asked to delete a non-existent user', async () => {
|
||||
@@ -786,6 +810,34 @@ describe('userRoutes', () => {
|
||||
expect(found).toBe(true);
|
||||
});
|
||||
|
||||
// Pins the P2025 check itself: without it the handler would report every
|
||||
// database failure as a 404, silently leaving the account in place.
|
||||
test('rethrows if the delete fails for any other reason', async () => {
|
||||
const errorLog = vi.spyOn(fastifyTestInstance.log, 'error');
|
||||
const spy = vi
|
||||
.spyOn(fastifyTestInstance.prisma.user, 'delete')
|
||||
.mockRejectedValueOnce(new Error('connection reset'));
|
||||
|
||||
try {
|
||||
const res = await superDelete(`/users/${defaultUserId}`);
|
||||
|
||||
expect(res.status).toBe(500);
|
||||
expect(res.body).not.toStrictEqual({
|
||||
type: 'error',
|
||||
message: 'not found'
|
||||
});
|
||||
expect(errorLog).toHaveBeenCalled();
|
||||
// The account must survive a failure the handler does not understand.
|
||||
const stillThere = await fastifyTestInstance.prisma.user.findFirst({
|
||||
where: { email: testUserData.email }
|
||||
});
|
||||
expect(stillThere).not.toBeNull();
|
||||
} finally {
|
||||
spy.mockRestore();
|
||||
errorLog.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
test('returns 403 if attempting to delete a different user', async () => {
|
||||
const res = await superDelete(`/users/${otherUserId}`);
|
||||
expect(res.status).toBe(403);
|
||||
|
||||
Reference in New Issue
Block a user