Skip to content

Commit f5a509b

Browse files
committed
msw: Implement GET /api/v1/me/updates request handler
1 parent a7852c0 commit f5a509b

File tree

3 files changed

+124
-1
lines changed

3 files changed

+124
-1
lines changed
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
import dependencies from './versions/dependencies.js';
22
import downloads from './versions/downloads.js';
3+
import followUpdates from './versions/follow-updates.js';
34
import getVersion from './versions/get.js';
45
import listVersions from './versions/list.js';
56
import patchVersion from './versions/patch.js';
67
import readme from './versions/readme.js';
78
import unyankVersion from './versions/unyank.js';
89
import yankVersion from './versions/yank.js';
910

10-
export default [listVersions, getVersion, patchVersion, yankVersion, unyankVersion, dependencies, downloads, readme];
11+
export default [
12+
listVersions,
13+
getVersion,
14+
patchVersion,
15+
yankVersion,
16+
unyankVersion,
17+
dependencies,
18+
downloads,
19+
readme,
20+
followUpdates,
21+
];
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { http, HttpResponse } from 'msw';
2+
3+
import { db } from '../../index.js';
4+
import { serializeVersion } from '../../serializers/version.js';
5+
import { pageParams } from '../../utils/handlers.js';
6+
import { getSession } from '../../utils/session.js';
7+
8+
export default http.get('/api/v1/me/updates', ({ request }) => {
9+
let { user } = getSession();
10+
if (!user) {
11+
return HttpResponse.json({ errors: [{ detail: 'must be logged in to perform that action' }] }, { status: 403 });
12+
}
13+
14+
let allVersions = user.followedCrates
15+
.flatMap(crate => db.version.findMany({ where: { crate: { id: { equals: crate.id } } } }))
16+
.sort((a, b) => b.id - a.id);
17+
18+
let { start, end, page, perPage } = pageParams(request);
19+
20+
let versions = allVersions.slice(start, end);
21+
let totalCount = allVersions.length;
22+
let totalPages = Math.ceil(totalCount / perPage);
23+
24+
return HttpResponse.json({
25+
versions: versions.map(v => serializeVersion(v)),
26+
meta: { more: page < totalPages },
27+
});
28+
});
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { assert, test } from 'vitest';
2+
3+
import { db } from '../../index.js';
4+
5+
test('returns 403 for unauthenticated user', async function () {
6+
let response = await fetch('/api/v1/me/updates');
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 latest versions of followed crates', async function () {
14+
let foo = db.crate.create({ name: 'foo' });
15+
db.version.create({ crate: foo, num: '1.2.3' });
16+
17+
let bar = db.crate.create({ name: 'bar' });
18+
db.version.create({ crate: bar, num: '0.8.6' });
19+
20+
let user = db.user.create({ followedCrates: [foo] });
21+
db.mswSession.create({ user });
22+
23+
let response = await fetch('/api/v1/me/updates');
24+
assert.strictEqual(response.status, 200);
25+
assert.deepEqual(await response.json(), {
26+
versions: [
27+
{
28+
id: 1,
29+
crate: 'foo',
30+
crate_size: 162_963,
31+
created_at: '2010-06-16T21:30:45Z',
32+
dl_path: '/api/v1/crates/foo/1.2.3/download',
33+
downloads: 3702,
34+
features: {},
35+
license: 'MIT',
36+
links: {
37+
dependencies: '/api/v1/crates/foo/1.2.3/dependencies',
38+
version_downloads: '/api/v1/crates/foo/1.2.3/downloads',
39+
},
40+
num: '1.2.3',
41+
published_by: null,
42+
readme_path: '/api/v1/crates/foo/1.2.3/readme',
43+
rust_version: null,
44+
updated_at: '2017-02-24T12:34:56Z',
45+
yanked: false,
46+
yank_message: null,
47+
},
48+
],
49+
meta: {
50+
more: false,
51+
},
52+
});
53+
});
54+
55+
test('empty case', async function () {
56+
let user = db.user.create();
57+
db.mswSession.create({ user });
58+
59+
let response = await fetch('/api/v1/me/updates');
60+
assert.strictEqual(response.status, 200);
61+
assert.deepEqual(await response.json(), {
62+
versions: [],
63+
meta: { more: false },
64+
});
65+
});
66+
67+
test('supports pagination', async function () {
68+
let crate = db.crate.create({ name: 'foo' });
69+
Array.from({ length: 25 }, () => db.version.create({ crate }));
70+
71+
let user = db.user.create({ followedCrates: [crate] });
72+
db.mswSession.create({ user });
73+
74+
let response = await fetch('/api/v1/me/updates?page=2');
75+
assert.strictEqual(response.status, 200);
76+
77+
let responsePayload = await response.json();
78+
assert.strictEqual(responsePayload.versions.length, 10);
79+
assert.deepEqual(
80+
responsePayload.versions.map(it => it.id),
81+
[15, 14, 13, 12, 11, 10, 9, 8, 7, 6],
82+
);
83+
assert.deepEqual(responsePayload.meta, { more: true });
84+
});

0 commit comments

Comments
 (0)