- Anyone who can see a play can read its comments; the player and the people they follow can write. The author, the player and admins can delete; comments can be reported (admins see the text). - Notifications: "commented on" for the player, "replied on" for earlier commenters, each with its own setting. Reaction and comment notifications now open the play. - A 💬 chip with the count next to reactions on the feed and recent plays, opening the thread on the app (/play/[id]) and the website. Threads refresh every few seconds while open. - Blocking removes comments between the two people. Plays with comments survive history trimming. - Privacy page updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011Y2iUsKEWDuRGjK5FPmcUP
39 lines
2.0 KiB
TypeScript
39 lines
2.0 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { notificationPath, notificationPrefs, notificationText } from './notifications';
|
|
|
|
const actor = { id: 'u1', username: 'bob', displayName: 'Bob', avatarUrl: null };
|
|
const track = { id: 't1', title: 'Teardrop', artist: 'Massive Attack', album: null, artworkUrl: null, durationMs: null, isrc: null, links: {} };
|
|
|
|
describe('notifications', () => {
|
|
it('words each kind', () => {
|
|
expect(notificationText({ type: 'reaction', actor, track, emoji: '🔥', message: null })).toEqual({
|
|
title: 'Bob reacted 🔥',
|
|
body: 'to Teardrop by Massive Attack',
|
|
});
|
|
expect(notificationText({ type: 'follow', actor: { ...actor, displayName: null }, track: null, emoji: null, message: null }).title).toBe(
|
|
'bob followed you',
|
|
);
|
|
expect(notificationText({ type: 'share', actor, track, emoji: null, message: 'so good' }).body).toBe('Teardrop by Massive Attack: “so good”');
|
|
});
|
|
|
|
it('links songs to the song and follows to the person', () => {
|
|
expect(notificationPath({ type: 'share', actor, track, listenId: null })).toBe('/t/t1');
|
|
expect(notificationPath({ type: 'follow', actor, track: null, listenId: null })).toBe('/u/bob');
|
|
});
|
|
|
|
it('opens the play for comments, replies and reactions', () => {
|
|
expect(notificationPath({ type: 'comment', actor, track, listenId: 'l1' })).toBe('/play/l1');
|
|
expect(notificationPath({ type: 'reaction', actor, track, listenId: 'l1' })).toBe('/play/l1');
|
|
// The play was trimmed from history: fall back to the song.
|
|
expect(notificationPath({ type: 'reaction', actor, track, listenId: null })).toBe('/t/t1');
|
|
expect(notificationText({ type: 'reply', actor, track, emoji: null, message: 'same' })).toEqual({
|
|
title: 'Bob replied on Teardrop by Massive Attack',
|
|
body: 'same',
|
|
});
|
|
});
|
|
|
|
it('treats missing settings as on', () => {
|
|
expect(notificationPrefs({ follow: false })).toEqual({ reaction: true, comment: true, reply: true, follow: false, share: true });
|
|
});
|
|
});
|