fix(api): 🐛 Add Reaction custom emoji data in statuses

This commit is contained in:
Jesse Wierzbinski 2025-05-26 15:13:56 +02:00
parent 8c0a20a743
commit 287f428a83
No known key found for this signature in database
3 changed files with 68 additions and 21 deletions

View file

@ -1,11 +1,37 @@
import { afterAll, describe, expect, test } from "bun:test";
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import { randomUUIDv7 } from "bun";
import { Emoji } from "~/classes/database/emoji";
import { Media } from "~/classes/database/media";
import { generateClient, getTestStatuses, getTestUsers } from "~/tests/utils";
const { users, deleteUsers } = await getTestUsers(3);
const timeline = (await getTestStatuses(2, users[0])).toReversed();
let emojiMedia: Media;
let customEmoji: Emoji;
beforeAll(async () => {
emojiMedia = await Media.insert({
id: randomUUIDv7(),
content: {
"image/png": {
content: "https://example.com/image.png",
remote: true,
},
},
});
customEmoji = await Emoji.insert({
id: randomUUIDv7(),
shortcode: "test_emoji",
visibleInPicker: true,
mediaId: emojiMedia.id,
});
});
afterAll(async () => {
await deleteUsers();
await customEmoji.delete();
await emojiMedia.delete();
});
describe("/api/v1/statuses/:id/reactions/:name", () => {
@ -40,6 +66,29 @@ describe("/api/v1/statuses/:id/reactions/:name", () => {
);
});
test("should add custom emoji reaction", async () => {
await using client = await generateClient(users[1]);
const { data, ok } = await client.createEmojiReaction(
timeline[0].id,
`:${customEmoji.data.shortcode}:`,
);
expect(ok).toBe(true);
expect(data.reactions).toContainEqual(
expect.objectContaining({
name: `:${customEmoji.data.shortcode}:`,
count: 1,
me: true,
}),
);
expect(data.emojis).toContainEqual(
expect.objectContaining({
shortcode: customEmoji.data.shortcode,
}),
);
});
test("should add multiple different reactions", async () => {
await using client1 = await generateClient(users[1]);
await using client2 = await generateClient(users[2]);

View file

@ -105,19 +105,12 @@ export default apiRoute((app) => {
emoji = unicodeEmoji;
}
// Use the User react method
try {
await user.react(note, emoji);
await user.react(note, emoji);
// Reload note to get updated reactions
await note.reload(user.id);
// Reload note to get updated reactions
await note.reload(user.id);
return context.json(await note.toApi(user), 201);
} catch {
// If it's already reacted, just return the current status
await note.reload(user.id);
return context.json(await note.toApi(user), 201);
}
return context.json(await note.toApi(user), 201);
},
);
@ -206,7 +199,6 @@ export default apiRoute((app) => {
emoji = unicodeEmoji;
}
// Use the User unreact method
await user.unreact(note, emoji);
// Reload note to get updated reactions

View file

@ -641,6 +641,18 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
);
}
const reactions = this.getReactions(userFetching ?? undefined).map(
// Remove account_ids
(r) => ({
...r,
account_ids: undefined,
}),
);
const emojis = data.emojis.concat(
data.reactions.map((r) => r.emoji).filter((v) => v !== null),
);
return {
id: data.id,
in_reply_to_id: data.replyId || null,
@ -652,7 +664,7 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
: undefined,
card: null,
content: replacedContent,
emojis: data.emojis.map((emoji) => new Emoji(emoji).toApi()),
emojis: emojis.map((emoji) => new Emoji(emoji).toApi()),
favourited: data.liked,
favourites_count: data.likeCount,
media_attachments: (data.attachments ?? []).map((a) =>
@ -699,13 +711,7 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
edited_at: data.updatedAt
? new Date(data.updatedAt).toISOString()
: null,
reactions: this.getReactions(userFetching ?? undefined).map(
// Remove account_ids
(r) => ({
...r,
account_ids: undefined,
}),
),
reactions,
text: data.contentSource,
};
}