Skip to content

Commit 0c94cfe

Browse files
committed
msw: Implement DELETE /api/v1/crates/:name/follow request handler
1 parent 55e8aae commit 0c94cfe

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import followCrate from './crates/follow.js';
33
import following from './crates/following.js';
44
import getCrate from './crates/get.js';
55
import listCrates from './crates/list.js';
6+
import unfollowCrate from './crates/unfollow.js';
67

7-
export default [listCrates, getCrate, deleteCrate, following, followCrate];
8+
export default [listCrates, getCrate, deleteCrate, following, followCrate, unfollowCrate];
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { http, HttpResponse } from 'msw';
2+
3+
import { db } from '../../index.js';
4+
import { notFound } from '../../utils/handlers.js';
5+
import { getSession } from '../../utils/session.js';
6+
7+
export default http.delete('/api/v1/crates/:name/follow', async ({ params }) => {
8+
let { user } = getSession();
9+
if (!user) {
10+
return HttpResponse.json({ errors: [{ detail: 'must be logged in to perform that action' }] }, { status: 403 });
11+
}
12+
13+
let crate = db.crate.findFirst({ where: { name: { equals: params.name } } });
14+
if (!crate) {
15+
return notFound();
16+
}
17+
18+
db.user.update({
19+
where: { id: { equals: user.id } },
20+
data: {
21+
followedCrates: user.followedCrates.filter(c => c.id !== crate.id),
22+
},
23+
});
24+
25+
return HttpResponse.json({ ok: true });
26+
});
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { assert, test } from 'vitest';
2+
3+
import { db } from '../../index.js';
4+
5+
test('returns 403 if unauthenticated', async function () {
6+
let response = await fetch('/api/v1/crates/foo/follow', { method: 'DELETE' });
7+
assert.strictEqual(response.status, 403);
8+
assert.deepEqual(await response.json(), {
9+
errors: [{ detail: 'must be logged in to perform that action' }],
10+
});
11+
});
12+
13+
test('returns 404 for unknown crates', async function () {
14+
let user = db.user.create();
15+
db.mswSession.create({ user });
16+
17+
let response = await fetch('/api/v1/crates/foo/follow', { method: 'DELETE' });
18+
assert.strictEqual(response.status, 404);
19+
assert.deepEqual(await response.json(), { errors: [{ detail: 'Not Found' }] });
20+
});
21+
22+
test('makes the authenticated user unfollow the crate', async function () {
23+
let crate = db.crate.create({ name: 'rand' });
24+
25+
let user = db.user.create({ followedCrates: [crate] });
26+
db.mswSession.create({ user });
27+
28+
assert.deepEqual(user.followedCrates, [crate]);
29+
30+
let response = await fetch('/api/v1/crates/rand/follow', { method: 'DELETE' });
31+
assert.strictEqual(response.status, 200);
32+
assert.deepEqual(await response.json(), { ok: true });
33+
34+
user = db.user.findFirst({ where: { id: user.id } });
35+
assert.deepEqual(user.followedCrates, []);
36+
});

0 commit comments

Comments
 (0)