Files
gerbeur/api/test/services/community-service.test.ts

105 lines
3.3 KiB
TypeScript

import {
createUser,
db,
insertComment,
insertDump,
insertPlaylist,
test,
} from "../helpers.ts";
import { assertEquals } from "@std/assert";
import {
communityStatsOf,
getCommunityStats,
refreshCommunityStats,
} from "../../services/community-service.ts";
const DAY = 86_400_000;
const ago = (ms: number) => new Date(Date.now() - ms).toISOString();
const week = () =>
[new Date(Date.now() - 7 * DAY), new Date(Date.now() + 60_000)] as const;
function vote(dumpId: string, n: number) {
db.prepare(`UPDATE dumps SET vote_count = ? WHERE id = ?;`).run(n, dumpId);
}
test("communityStatsOf: the period's top public dumps, members, public playlists and totals", async () => {
const ann = await createUser({ createdAt: ago(20 * DAY) });
const bob = await createUser({ invitedBy: ann.id, createdAt: ago(2 * DAY) });
const cy = await createUser({ createdAt: ago(DAY) });
const hit = insertDump({ userId: bob.id, title: "Hit" });
vote(hit.id, 5);
const tie = insertDump({ userId: ann.id, title: "Tie", createdAt: ago(DAY) });
vote(tie.id, 2);
const newer = insertDump({ userId: ann.id, title: "Newer" });
vote(newer.id, 2);
insertDump({ userId: ann.id, title: "No votes" });
vote(insertDump({ userId: ann.id, title: "Private", isPrivate: true }).id, 9);
vote(
insertDump({ userId: ann.id, title: "Too old", createdAt: ago(10 * DAY) })
.id,
9,
);
insertComment({ dumpId: hit.id, userId: cy.id, body: "nice" });
insertPlaylist({ userId: ann.id, title: "Small" });
const full = insertPlaylist({ userId: bob.id, title: "Full" });
insertPlaylist({ userId: bob.id, title: "Hidden", isPublic: false });
// Bob's private dump isn't counted: every reader gets the same figures.
const secret = insertDump({
userId: bob.id,
title: "Secret",
isPrivate: true,
});
db.prepare(
`INSERT INTO playlist_dumps (playlist_id, dump_id, position, added_at) VALUES (?, ?, 0, ?), (?, ?, 1, ?), (?, ?, 2, ?);`,
).run(
full.id,
hit.id,
ago(0),
full.id,
tie.id,
ago(0),
full.id,
secret.id,
ago(0),
);
const stats = communityStatsOf(...week());
assertEquals(stats.top.map((d) => d.title), ["Hit", "Newer", "Tie"]);
assertEquals(stats.top[0].ownerUsername, bob.username);
assertEquals(
stats.members.map((m) => [m.username, m.invitedByUsername]),
[[bob.username, ann.username], [cy.username, undefined]],
);
assertEquals(
stats.playlists.map((p) => [p.title, p.dumpCount]),
[["Full", 2], ["Small", 0]],
);
assertEquals(stats.totals, { dumps: 4, upvotes: 0, comments: 1 });
assertEquals(stats.chatMessages, 0);
});
test("getCommunityStats: serves the last refresh, of the week or the month", async () => {
const ann = await createUser({ createdAt: ago(20 * DAY) });
vote(
insertDump({ userId: ann.id, title: "Month", createdAt: ago(20 * DAY) })
.id,
1,
);
refreshCommunityStats();
assertEquals(getCommunityStats("weekly").top, []);
assertEquals(getCommunityStats("monthly").top.map((d) => d.title), [
"Month",
]);
assertEquals(getCommunityStats("monthly").members.length, 1);
vote(
insertDump({ userId: ann.id, title: "Later", createdAt: ago(1000) }).id,
1,
);
assertEquals(getCommunityStats("weekly").top, []);
refreshCommunityStats();
assertEquals(getCommunityStats("weekly").top.map((d) => d.title), [
"Later",
]);
});