From e293bd280d8fc3f2f102629b2e84cefc8ff61485 Mon Sep 17 00:00:00 2001 From: Jesse Wierzbinski Date: Mon, 9 Dec 2024 15:30:18 +0100 Subject: [PATCH] fix(api): :bug: Fix duplicated mentions, general refactorings --- api/api/v1/notifications/index.test.ts | 2 +- api/api/v1/notifications/index.ts | 32 +++++++++++++------------- api/api/v1/statuses/index.test.ts | 3 +++ classes/functions/status.ts | 19 +++++++-------- classes/inbox/processor.test.ts | 2 +- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/api/api/v1/notifications/index.test.ts b/api/api/v1/notifications/index.test.ts index 1f6aab61..d510e169 100644 --- a/api/api/v1/notifications/index.test.ts +++ b/api/api/v1/notifications/index.test.ts @@ -143,7 +143,7 @@ describe(meta.route, () => { const objects = (await response.json()) as ApiNotification[]; - expect(objects.length).toBe(2); + expect(objects.length).toBe(3); // There should be no element with a status with id of timeline[0].id expect(objects).not.toContainEqual( expect.objectContaining({ diff --git a/api/api/v1/notifications/index.ts b/api/api/v1/notifications/index.ts index 8ed563a3..4b179b30 100644 --- a/api/api/v1/notifications/index.ts +++ b/api/api/v1/notifications/index.ts @@ -153,25 +153,25 @@ export default apiRoute((app) => // Filters in `Filters` table have keyword in `FilterKeywords` table (use LIKE) // Filters table has a userId and a context which is an array sql`NOT EXISTS ( - SELECT 1 - FROM "Filters" - WHERE "Filters"."userId" = ${user.id} - AND "Filters"."filter_action" = 'hide' - AND EXISTS ( - SELECT 1 - FROM "FilterKeywords", "Notifications" as "n_inner", "Notes" - WHERE "FilterKeywords"."filterId" = "Filters"."id" - AND "n_inner"."noteId" = "Notes"."id" - AND "Notes"."content" LIKE - '%' || "FilterKeywords"."keyword" || '%' - AND "n_inner"."id" = "Notifications"."id" - ) - AND "Filters"."context" @> ARRAY['notifications'] - )`, + SELECT 1 + FROM "Filters" + WHERE "Filters"."userId" = ${user.id} + AND "Filters"."filter_action" = 'hide' + AND EXISTS ( + SELECT 1 + FROM "FilterKeywords", "Notifications" as "n_inner", "Notes" + WHERE "FilterKeywords"."filterId" = "Filters"."id" + AND "n_inner"."noteId" = "Notes"."id" + AND "Notes"."content" LIKE + '%' || "FilterKeywords"."keyword" || '%' + AND "n_inner"."id" = "Notifications"."id" + ) + AND "Filters"."context" @> ARRAY['notifications'] + )`, ), limit, context.req.url, - user?.id, + user.id, ); return context.json( diff --git a/api/api/v1/statuses/index.test.ts b/api/api/v1/statuses/index.test.ts index 4452cfb9..43bc84d1 100644 --- a/api/api/v1/statuses/index.test.ts +++ b/api/api/v1/statuses/index.test.ts @@ -310,6 +310,9 @@ describe(meta.route, () => { const object = (await response.json()) as ApiStatus; + expect(object.content).toBe( + `

Hello, @${users[1].data.username}!

`, + ); expect(object.mentions).toBeArrayOfSize(1); expect(object.mentions[0]).toMatchObject({ id: users[1].id, diff --git a/classes/functions/status.ts b/classes/functions/status.ts index bf5ecba6..9b7f118a 100644 --- a/classes/functions/status.ts +++ b/classes/functions/status.ts @@ -298,20 +298,17 @@ export const replaceTextMentions = (text: string, mentions: User[]): string => { ); } - return finalText - .replace( - createRegExp( + return finalText.replace( + createRegExp( + exactly( exactly(`@${username}`) .notBefore(anyOf(letter, digit, charIn("@"))) .notAfter(anyOf(letter, digit, charIn("@"))), - [global], - ), - linkTemplate(`@${username}@${baseHost}`), - ) - .replaceAll( - `@${username}@${baseHost}`, - linkTemplate(`@${username}@${baseHost}`), - ); + ).or(exactly(`@${username}@${baseHost}`)), + [global], + ), + linkTemplate(`@${username}@${baseHost}`), + ); }, text); }; diff --git a/classes/inbox/processor.test.ts b/classes/inbox/processor.test.ts index 2b56be2c..9ca79afe 100644 --- a/classes/inbox/processor.test.ts +++ b/classes/inbox/processor.test.ts @@ -43,7 +43,6 @@ mock.module("@versia/kit/db", () => ({ }, Notification: { fromSql: jest.fn(), - insert: jest.fn(), }, })); @@ -242,6 +241,7 @@ describe("InboxProcessor", () => { id: "followee-id", data: { isLocked: false }, sendFollowAccept: jest.fn(), + notify: jest.fn(), }; const mockRelationship = { data: { following: false },