v4: a dump or playlist going public notifies its followers — a private dump notified no one when posted, and nothing told its followers when it was made public: the poster's followers never learnt of it, nor did the followers of the public playlists holding it. Likewise, the dumps added to a playlist while it was private were never notified to its followers. updateDump and replaceFileDump now call notifyIfWentPublic, which notifies the poster's followers (user_dump_posted) and, through the new notifyPlaylistFollowersNowPublic, the followers of each public playlist holding the dump (playlist_dump_added). updatePlaylist calls the same function when a playlist goes public, for each public dump in it, from the bottom up. A follower hears of a dump once both it and the playlist are public; the source keys stop a dump made private and public again from notifying twice. 256 backend tests pass, and deno check, deno fmt and doc:lint are clean.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -320,6 +320,33 @@ test("adding to a followed public playlist notifies followers, private dumps exc
|
||||
});
|
||||
});
|
||||
|
||||
test("a playlist going public notifies its followers of the public dumps added meanwhile", async () => {
|
||||
const owner = await createUser();
|
||||
const follower = await createUser();
|
||||
const { id } = insertPlaylist({ userId: owner.id, title: "Mix" });
|
||||
await put(`/api/me/follow/playlists/${id}`, { auth: follower.auth });
|
||||
const before = insertDump({ userId: owner.id, title: "Before" });
|
||||
await post(`/api/playlists/${id}/dumps/${before.id}`, { auth: owner.auth });
|
||||
db.prepare(`DELETE FROM notifications WHERE user_id = ?;`).run(owner.id);
|
||||
const setPublic = (isPublic: boolean) =>
|
||||
put(`/api/playlists/${id}`, { auth: owner.auth, json: { isPublic } });
|
||||
|
||||
await setPublic(false);
|
||||
const during = insertDump({ userId: owner.id, title: "During" });
|
||||
const priv = insertDump({ userId: owner.id, isPrivate: true });
|
||||
for (const d of [during, priv]) {
|
||||
await post(`/api/playlists/${id}/dumps/${d.id}`, { auth: owner.auth });
|
||||
}
|
||||
assertEquals(count(`SELECT COUNT(*) as n FROM notifications;`), 1);
|
||||
await setPublic(true);
|
||||
const titles = (db.prepare(
|
||||
`SELECT data FROM notifications WHERE user_id = ? ORDER BY created_at;`,
|
||||
).all(follower.id) as { data: string }[]).map((n) =>
|
||||
JSON.parse(n.data).dumpTitle
|
||||
);
|
||||
assertEquals(titles, ["Before", "During"]);
|
||||
});
|
||||
|
||||
test("playlist covers: upload and serve", async () => {
|
||||
const owner = await createUser();
|
||||
const other = await createUser();
|
||||
|
||||
Reference in New Issue
Block a user