Skip to content

Commit 28e2830

Browse files
committed
msw: Implement PUT /api/v1/users/:id endpoint
1 parent 68e0c23 commit 28e2830

File tree

3 files changed

+130
-2
lines changed

3 files changed

+130
-2
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import { site_metadata } from './metadata';
2-
import { find_user } from './users';
2+
import { find_user, update_user } from './users';
33

4-
export const handlers = [site_metadata, find_user];
4+
export const handlers = [site_metadata, find_user, update_user];

packages/crates-io-msw/handlers/users.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { http, HttpResponse } from 'msw';
22

33
import { db } from '../db';
4+
import { getSession } from '../utils/session.js';
45
import { notFound } from './-utils';
56

67
export const find_user = http.get('/api/v1/users/:login', ({ params }) => {
@@ -14,6 +15,48 @@ export const find_user = http.get('/api/v1/users/:login', ({ params }) => {
1415
return HttpResponse.json({ user: serializeUser(user) });
1516
});
1617

18+
export const update_user = http.put('/api/v1/users/:id', async ({ params, request }) => {
19+
let { user } = getSession(db);
20+
if (!user) {
21+
// unfortunately, it's hard to tell from the Rust code if this is the correct response
22+
// in this case, but since it's used elsewhere I will assume for now that it's correct.
23+
return HttpResponse.json({ errors: [{ detail: 'must be logged in to perform that action' }] }, { status: 403 });
24+
}
25+
26+
if (user.id.toString() !== params.id) {
27+
return HttpResponse.json({ errors: [{ detail: 'current user does not match requested user' }] }, { status: 400 });
28+
}
29+
30+
let json = await request.json();
31+
if (!json || !json.user) {
32+
return HttpResponse.json({ errors: [{ detail: 'invalid json request' }] }, { status: 400 });
33+
}
34+
35+
if (json.user.publish_notifications !== undefined) {
36+
db.user.update({
37+
where: { id: { equals: user.id } },
38+
data: { publish_notifications: json.user.publish_notifications },
39+
});
40+
}
41+
42+
if (json.user.email !== undefined) {
43+
if (!json.user.email) {
44+
return HttpResponse.json({ errors: [{ detail: 'empty email rejected' }] }, { status: 400 });
45+
}
46+
47+
db.user.update({
48+
where: { id: { equals: user.id } },
49+
data: {
50+
email: json.user.email,
51+
email_verified: false,
52+
email_verification_token: 'secret123',
53+
},
54+
});
55+
}
56+
57+
return HttpResponse.json({ ok: true });
58+
});
59+
1760
function serializeUser(user) {
1861
delete user.email;
1962
delete user.email_verification_token;
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { describe, test } from 'vitest';
2+
3+
import { db } from '../../db';
4+
5+
describe('PUT /api/v1/users/:id', () => {
6+
test('updates the user with a new email address', async ({ expect }) => {
7+
let user = db.user.create({ email: '[email protected]' });
8+
db.mswSession.create({ user });
9+
10+
let body = JSON.stringify({ user: { email: '[email protected]' } });
11+
let response = await fetch(`/api/v1/users/${user.id}`, { method: 'PUT', body });
12+
expect(response.status).toBe(200);
13+
expect(await response.json()).toEqual({ ok: true });
14+
15+
user = db.user.findFirst({ where: { id: user.id } });
16+
expect(user.email).toBe('[email protected]');
17+
expect(user.email_verified).toBe(false);
18+
expect(user.email_verification_token).toBe('secret123');
19+
});
20+
21+
test('updates the `publish_notifications` settings', async ({ expect }) => {
22+
let user = db.user.create();
23+
db.mswSession.create({ user });
24+
expect(user.publish_notifications).toBe(true);
25+
26+
let body = JSON.stringify({ user: { publish_notifications: false } });
27+
let response = await fetch(`/api/v1/users/${user.id}`, { method: 'PUT', body });
28+
expect(response.status).toBe(200);
29+
expect(await response.json()).toEqual({ ok: true });
30+
31+
user = db.user.findFirst({ where: { id: user.id } });
32+
expect(user.publish_notifications).toBe(false);
33+
});
34+
35+
test('returns 403 when not logged in', async ({ expect }) => {
36+
let user = db.user.create({ email: '[email protected]' });
37+
38+
let body = JSON.stringify({ user: { email: '[email protected]' } });
39+
let response = await fetch(`/api/v1/users/${user.id}`, { method: 'PUT', body });
40+
expect(response.status).toBe(403);
41+
expect(await response.json()).toEqual({ errors: [{ detail: 'must be logged in to perform that action' }] });
42+
43+
user = db.user.findFirst({ where: { id: user.id } });
44+
expect(user.email).toBe('[email protected]');
45+
});
46+
47+
test('returns 400 when requesting the wrong user id', async ({ expect }) => {
48+
let user = db.user.create({ email: '[email protected]' });
49+
db.mswSession.create({ user });
50+
51+
let body = JSON.stringify({ user: { email: '[email protected]' } });
52+
let response = await fetch(`/api/v1/users/wrong-id`, { method: 'PUT', body });
53+
expect(response.status).toBe(400);
54+
expect(await response.json()).toEqual({ errors: [{ detail: 'current user does not match requested user' }] });
55+
56+
user = db.user.findFirst({ where: { id: user.id } });
57+
expect(user.email).toBe('[email protected]');
58+
});
59+
60+
test('returns 400 when sending an invalid payload', async ({ expect }) => {
61+
let user = db.user.create({ email: '[email protected]' });
62+
db.mswSession.create({ user });
63+
64+
let body = JSON.stringify({});
65+
let response = await fetch(`/api/v1/users/${user.id}`, { method: 'PUT', body });
66+
expect(response.status).toBe(400);
67+
expect(await response.json()).toEqual({ errors: [{ detail: 'invalid json request' }] });
68+
69+
user = db.user.findFirst({ where: { id: user.id } });
70+
expect(user.email).toBe('[email protected]');
71+
});
72+
73+
test('returns 400 when sending an empty email address', async ({ expect }) => {
74+
let user = db.user.create({ email: '[email protected]' });
75+
db.mswSession.create({ user });
76+
77+
let body = JSON.stringify({ user: { email: '' } });
78+
let response = await fetch(`/api/v1/users/${user.id}`, { method: 'PUT', body });
79+
expect(response.status).toBe(400);
80+
expect(await response.json()).toEqual({ errors: [{ detail: 'empty email rejected' }] });
81+
82+
user = db.user.findFirst({ where: { id: user.id } });
83+
expect(user.email).toBe('[email protected]');
84+
});
85+
});

0 commit comments

Comments
 (0)