From 8e5d68144cb3f8d86b1db4587d1fd70b2aacba47 Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Sun, 12 May 2024 15:07:55 -1000 Subject: [PATCH] fix(api): :bug: Fix regression in emoji parsing caused by incorrectly changed regex --- database/entities/Emoji.ts | 4 +-- server/api/api/v1/statuses/index.test.ts | 41 +++++++++++++++++++++++- utils/api.ts | 7 ++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/database/entities/Emoji.ts b/database/entities/Emoji.ts index 6ccee689..4b80b605 100644 --- a/database/entities/Emoji.ts +++ b/database/entities/Emoji.ts @@ -1,4 +1,4 @@ -import { emojiValidator } from "@api"; +import { emojiValidator, emojiValidatorWithColons } from "@api"; import { proxyUrl } from "@response"; import { type InferSelectModel, and, eq } from "drizzle-orm"; import type * as Lysand from "lysand-types"; @@ -17,7 +17,7 @@ export type EmojiWithInstance = InferSelectModel & { * @returns An array of emojis */ export const parseEmojis = async (text: string) => { - const matches = text.match(emojiValidator); + const matches = text.match(emojiValidatorWithColons); if (!matches) return []; const emojis = await db.query.Emojis.findMany({ where: (emoji, { eq, or }) => diff --git a/server/api/api/v1/statuses/index.test.ts b/server/api/api/v1/statuses/index.test.ts index 041dc4a5..c7b037f3 100644 --- a/server/api/api/v1/statuses/index.test.ts +++ b/server/api/api/v1/statuses/index.test.ts @@ -1,5 +1,8 @@ -import { afterAll, describe, expect, test } from "bun:test"; +import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { config } from "config-manager"; +import { eq } from "drizzle-orm"; +import { db } from "~drizzle/db"; +import { Emojis } from "~drizzle/schema"; import { deleteOldTestUsers, getTestUsers, @@ -14,6 +17,16 @@ const { users, tokens, deleteUsers } = await getTestUsers(5); afterAll(async () => { await deleteUsers(); + await db.delete(Emojis).where(eq(Emojis.shortcode, "test")); +}); + +beforeAll(async () => { + await db.insert(Emojis).values({ + contentType: "image/png", + shortcode: "test", + url: "https://example.com/test.png", + visibleInPicker: true, + }); }); describe(meta.route, () => { @@ -278,6 +291,32 @@ describe(meta.route, () => { expect(object2.quote?.id).toBe(object.id); }); + test("should correctly parse emojis", async () => { + const response = await sendTestRequest( + new Request(new URL(meta.route, config.http.base_url), { + method: "POST", + headers: { + Authorization: `Bearer ${tokens[0].accessToken}`, + }, + body: new URLSearchParams({ + status: "Hello, :test:!", + federate: "false", + }), + }), + ); + + expect(response.status).toBe(200); + expect(response.headers.get("content-type")).toBe("application/json"); + + const object = (await response.json()) as APIStatus; + + expect(object.emojis).toBeArrayOfSize(1); + expect(object.emojis[0]).toMatchObject({ + shortcode: "test", + url: expect.stringContaining("/media/proxy/"), + }); + }); + describe("mentions testing", () => { test("should correctly parse @mentions", async () => { const response = await sendTestRequest( diff --git a/utils/api.ts b/utils/api.ts index 71f5c1ef..fc1233f0 100644 --- a/utils/api.ts +++ b/utils/api.ts @@ -57,6 +57,13 @@ export const emojiValidator = createRegExp( [caseInsensitive], ); +export const emojiValidatorWithColons = createRegExp( + exactly(":"), + oneOrMore(letter.or(digit).or(exactly("_")).or(exactly("-"))), + exactly(":"), + [caseInsensitive], +); + export const handleZodError = ( result: | { success: true; data?: object }