mirror of
https://github.com/versia-pub/server.git
synced 2026-01-26 04:06:01 +01:00
fix(api): 🐛 Fix bugs where favourite/unfavourite could return negative values (+ add tests)
This commit is contained in:
parent
d2767b0862
commit
1d55570abd
55
server/api/api/v1/statuses/:id/favourite.test.ts
Normal file
55
server/api/api/v1/statuses/:id/favourite.test.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import { afterAll, describe, expect, test } from "bun:test";
|
||||
import { config } from "config-manager";
|
||||
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
|
||||
import type { Status as APIStatus } from "~/types/mastodon/status";
|
||||
import { meta } from "./favourite";
|
||||
|
||||
const { users, tokens, deleteUsers } = await getTestUsers(5);
|
||||
const timeline = (await getTestStatuses(2, users[0])).toReversed();
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteUsers();
|
||||
});
|
||||
|
||||
// /api/v1/statuses/:id/favourite
|
||||
describe(meta.route, () => {
|
||||
test("should return 401 if not authenticated", async () => {
|
||||
const response = await sendTestRequest(
|
||||
new Request(
|
||||
new URL(
|
||||
meta.route.replace(":id", timeline[0].id),
|
||||
config.http.base_url,
|
||||
),
|
||||
{
|
||||
method: "POST",
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(401);
|
||||
});
|
||||
|
||||
test("should favourite post", async () => {
|
||||
const response = await sendTestRequest(
|
||||
new Request(
|
||||
new URL(
|
||||
meta.route.replace(":id", timeline[0].id),
|
||||
config.http.base_url,
|
||||
),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const json = (await response.json()) as APIStatus;
|
||||
|
||||
expect(json.favourited).toBe(true);
|
||||
expect(json.favourites_count).toBe(1);
|
||||
});
|
||||
});
|
||||
|
|
@ -6,7 +6,6 @@ import { z } from "zod";
|
|||
import { createLike } from "~/database/entities/Like";
|
||||
import { db } from "~/drizzle/db";
|
||||
import { Note } from "~/packages/database-interface/note";
|
||||
import type { Status as APIStatus } from "~/types/mastodon/status";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -56,10 +55,10 @@ export default (app: Hono) =>
|
|||
await createLike(user, note);
|
||||
}
|
||||
|
||||
return jsonResponse({
|
||||
...(await note.toAPI(user)),
|
||||
favourited: true,
|
||||
favourites_count: note.getStatus().likeCount + 1,
|
||||
} as APIStatus);
|
||||
const newNote = await Note.fromId(id, user.id);
|
||||
|
||||
if (!newNote) return errorResponse("Record not found", 404);
|
||||
|
||||
return jsonResponse(await newNote.toAPI(user));
|
||||
},
|
||||
);
|
||||
|
|
|
|||
91
server/api/api/v1/statuses/:id/unfavourite.test.ts
Normal file
91
server/api/api/v1/statuses/:id/unfavourite.test.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { config } from "config-manager";
|
||||
import { getTestStatuses, getTestUsers, sendTestRequest } from "~/tests/utils";
|
||||
import type { Status as APIStatus } from "~/types/mastodon/status";
|
||||
import { meta } from "./unfavourite";
|
||||
|
||||
const { users, tokens, deleteUsers } = await getTestUsers(5);
|
||||
const timeline = (await getTestStatuses(2, users[0])).toReversed();
|
||||
|
||||
afterAll(async () => {
|
||||
await deleteUsers();
|
||||
});
|
||||
|
||||
// /api/v1/statuses/:id/unfavourite
|
||||
describe(meta.route, () => {
|
||||
test("should return 401 if not authenticated", async () => {
|
||||
const response = await sendTestRequest(
|
||||
new Request(
|
||||
new URL(
|
||||
meta.route.replace(":id", timeline[0].id),
|
||||
config.http.base_url,
|
||||
),
|
||||
{
|
||||
method: "POST",
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(401);
|
||||
});
|
||||
|
||||
test("should be able to unfavourite post that is not favourited", async () => {
|
||||
const response = await sendTestRequest(
|
||||
new Request(
|
||||
new URL(
|
||||
meta.route.replace(":id", timeline[0].id),
|
||||
config.http.base_url,
|
||||
),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
test("should unfavourite post", async () => {
|
||||
beforeAll(async () => {
|
||||
await sendTestRequest(
|
||||
new Request(
|
||||
new URL(
|
||||
`/api/v1/statuses/${timeline[1].id}/favourite`,
|
||||
config.http.base_url,
|
||||
),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
const response = await sendTestRequest(
|
||||
new Request(
|
||||
new URL(
|
||||
meta.route.replace(":id", timeline[1].id),
|
||||
config.http.base_url,
|
||||
),
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokens[1].accessToken}`,
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
|
||||
const json = (await response.json()) as APIStatus;
|
||||
|
||||
expect(json.favourited).toBe(false);
|
||||
expect(json.favourites_count).toBe(0);
|
||||
});
|
||||
});
|
||||
|
|
@ -5,7 +5,6 @@ import type { Hono } from "hono";
|
|||
import { z } from "zod";
|
||||
import { deleteLike } from "~/database/entities/Like";
|
||||
import { Note } from "~/packages/database-interface/note";
|
||||
import type { Status as APIStatus } from "~/types/mastodon/status";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -44,10 +43,10 @@ export default (app: Hono) =>
|
|||
|
||||
await deleteLike(user, note);
|
||||
|
||||
return jsonResponse({
|
||||
...(await note.toAPI(user)),
|
||||
favourited: false,
|
||||
favourites_count: note.getStatus().likeCount - 1,
|
||||
} as APIStatus);
|
||||
const newNote = await Note.fromId(id, user.id);
|
||||
|
||||
if (!newNote) return errorResponse("Record not found", 404);
|
||||
|
||||
return jsonResponse(await newNote.toAPI(user));
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import type { Hono } from "hono";
|
|||
import { z } from "zod";
|
||||
import { Notes } from "~/drizzle/schema";
|
||||
import { Note } from "~/packages/database-interface/note";
|
||||
import type { Status as APIStatus } from "~/types/mastodon/status";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
|
|
@ -59,10 +58,10 @@ export default (app: Hono) =>
|
|||
|
||||
await existingReblog.delete();
|
||||
|
||||
return jsonResponse({
|
||||
...(await foundStatus.toAPI(user)),
|
||||
reblogged: false,
|
||||
reblogs_count: foundStatus.getStatus().reblogCount - 1,
|
||||
} as APIStatus);
|
||||
const newNote = await Note.fromId(id, user.id);
|
||||
|
||||
if (!newNote) return errorResponse("Record not found", 404);
|
||||
|
||||
return jsonResponse(await newNote.toAPI(user));
|
||||
},
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue