mirror of
https://github.com/versia-pub/server.git
synced 2025-12-07 08:48:19 +01:00
feat(api): ✨ Add notifications for follow requests again and mentions
This commit is contained in:
parent
06bcbbe451
commit
47133ac3fe
|
|
@ -35,6 +35,7 @@ import {
|
|||
status,
|
||||
statusToMentions,
|
||||
user,
|
||||
notification,
|
||||
} from "~drizzle/schema";
|
||||
import { LogLevel } from "~packages/log-manager";
|
||||
import type { Note } from "~types/lysand/Object";
|
||||
|
|
@ -995,6 +996,18 @@ export const createNewStatus = async (
|
|||
.where(inArray(attachment.id, media_attachments));
|
||||
}
|
||||
|
||||
// Send notifications for mentioned local users
|
||||
for (const mention of mentions ?? []) {
|
||||
if (mention.instanceId === null) {
|
||||
await db.insert(notification).values({
|
||||
accountId: author.id,
|
||||
notifiedId: mention.id,
|
||||
type: "mention",
|
||||
statusId: newStatus.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
(await findFirstStatuses({
|
||||
where: (status, { eq }) => eq(status.id, newStatus.id),
|
||||
|
|
@ -1146,6 +1159,18 @@ export const editStatus = async (
|
|||
.execute();
|
||||
}
|
||||
|
||||
// Send notifications for mentioned local users
|
||||
for (const mention of mentions ?? []) {
|
||||
if (mention.instanceId === null) {
|
||||
await db.insert(notification).values({
|
||||
accountId: statusToEdit.authorId,
|
||||
notifiedId: mention.id,
|
||||
type: "mention",
|
||||
statusId: updated.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Set attachment parents
|
||||
await db
|
||||
.update(attachment)
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ export const followRequestUser = async (
|
|||
notify = false,
|
||||
languages: string[] = [],
|
||||
): Promise<InferSelectModel<typeof relationship>> => {
|
||||
const isRemote = follower.instanceId !== followee.instanceId;
|
||||
const isRemote = followee.instanceId !== null;
|
||||
|
||||
const updatedRelationship = (
|
||||
await db
|
||||
|
|
@ -226,9 +226,9 @@ export const followRequestUser = async (
|
|||
}
|
||||
} else {
|
||||
await db.insert(notification).values({
|
||||
accountId: followee.id,
|
||||
accountId: follower.id,
|
||||
type: followee.isLocked ? "follow_request" : "follow",
|
||||
notifiedId: follower.id,
|
||||
notifiedId: followee.id,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
110
server/api/api/v1/notifications/index.test.ts
Normal file
110
server/api/api/v1/notifications/index.test.ts
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { config } from "config-manager";
|
||||
import {
|
||||
deleteOldTestUsers,
|
||||
getTestStatuses,
|
||||
getTestUsers,
|
||||
sendTestRequest,
|
||||
} from "~tests/utils";
|
||||
import { meta } from "./index";
|
||||
import type { Notification as APINotification } from "~types/mastodon/notification";
|
||||
|
||||
await deleteOldTestUsers();
|
||||
|
||||
const { users, tokens, deleteUsers } = await getTestUsers(2);
|
||||
const timeline = (await getTestStatuses(40, users[0])).toReversed();
|
||||
// Create some test notifications: follow, favourite, reblog, mention
|
||||
beforeAll(async () => {
|
||||
await fetch(
|
||||
new URL(`/api/v1/accounts/${users[0].id}/follow`, config.http.base_url),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
await fetch(
|
||||
new URL(
|
||||
`/api/v1/statuses/${timeline[0].id}/favourite`,
|
||||
config.http.base_url,
|
||||
),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
await fetch(
|
||||
new URL(
|
||||
`/api/v1/statuses/${timeline[0].id}/reblog`,
|
||||
config.http.base_url,
|
||||
),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
await fetch(new URL("/api/v1/statuses", config.http.base_url), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
status: `@${users[0].username} test mention`,
|
||||
visibility: "direct",
|
||||
federate: false,
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteUsers();
|
||||
});
|
||||
|
||||
// /api/v1/notifications
|
||||
describe(meta.route, () => {
|
||||
test("should return 401 if not authenticated", async () => {
|
||||
const response = await sendTestRequest(
|
||||
new Request(new URL(meta.route, config.http.base_url)),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(401);
|
||||
});
|
||||
|
||||
test("should return 200 with notifications", async () => {
|
||||
const response = await sendTestRequest(
|
||||
new Request(new URL(meta.route, config.http.base_url), {
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[0].accessToken}`,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers.get("content-type")).toBe("application/json");
|
||||
|
||||
const objects = (await response.json()) as APINotification[];
|
||||
|
||||
expect(objects.length).toBe(4);
|
||||
for (const [index, notification] of objects.entries()) {
|
||||
expect(notification.account).toBeDefined();
|
||||
expect(notification.account?.id).toBe(users[1].id);
|
||||
expect(notification.created_at).toBeDefined();
|
||||
expect(notification.id).toBeDefined();
|
||||
expect(notification.type).toBeDefined();
|
||||
expect(notification.type).toBe(
|
||||
["follow", "favourite", "reblog", "mention"].toReversed()[
|
||||
index
|
||||
],
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -47,7 +47,6 @@ export const schema = z.object({
|
|||
"group_reblog",
|
||||
"group_favourite",
|
||||
"user_approved",
|
||||
"update",
|
||||
])
|
||||
.array()
|
||||
.optional(),
|
||||
|
|
@ -73,7 +72,6 @@ export const schema = z.object({
|
|||
"group_reblog",
|
||||
"group_favourite",
|
||||
"user_approved",
|
||||
"update",
|
||||
])
|
||||
.array()
|
||||
.optional(),
|
||||
|
|
|
|||
Loading…
Reference in a new issue