Finish full rewrite of server and testing systems

This commit is contained in:
Jesse Wierzbinski 2024-03-10 16:04:14 -10:00
parent 0e4d6b401c
commit 0541776d3d
No known key found for this signature in database
32 changed files with 1168 additions and 916 deletions

View file

@ -1 +0,0 @@
// Empty file

View file

@ -1,8 +1,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { getConfig } from "~classes/configmanager";
import type { Token } from "@prisma/client";
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import { ConfigManager } from "config-manager";
import { client } from "~database/datasource";
import { TokenType } from "~database/entities/Token";
import {
@ -11,8 +9,10 @@ import {
} from "~database/entities/User";
import type { APIEmoji } from "~types/entities/emoji";
import type { APIInstance } from "~types/entities/instance";
import { sendTestRequest, wrapRelativeUrl } from "./utils";
const config = getConfig();
const config = await new ConfigManager({}).getConfig();
const base_url = config.http.base_url;
let token: Token;
let user: UserWithRelations;
@ -71,14 +71,16 @@ describe("API Tests", () => {
describe("GET /api/v1/instance", () => {
test("should return an APIInstance object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/instance`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(`${base_url}/api/v1/instance`, base_url),
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -117,15 +119,21 @@ describe("API Tests", () => {
},
});
});
test("should return an array of at least one custom emoji", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/custom_emojis`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`${base_url}/api/v1/custom_emojis`,
base_url
),
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
)
);
expect(response.status).toBe(200);
@ -139,6 +147,7 @@ describe("API Tests", () => {
expect(emojis[0].shortcode).toBeString();
expect(emojis[0].url).toBeString();
});
afterAll(async () => {
await client.emoji.deleteMany({
where: {

View file

@ -1,6 +1,3 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { getConfig } from "~classes/configmanager";
import type { Token } from "@prisma/client";
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import { client } from "~database/datasource";
@ -12,21 +9,24 @@ import {
import type { APIAccount } from "~types/entities/account";
import type { APIRelationship } from "~types/entities/relationship";
import type { APIStatus } from "~types/entities/status";
import { ConfigManager } from "config-manager";
import { sendTestRequest, wrapRelativeUrl } from "~tests/utils";
const config = getConfig();
const config = await new ConfigManager({}).getConfig();
const base_url = config.http.base_url;
let token: Token;
let user: UserWithRelations;
let user2: UserWithRelations;
beforeAll(async () => {
/* await client.user.deleteMany({
await client.user.deleteMany({
where: {
username: {
in: ["test", "test2"],
},
},
}); */
});
user = await createNewLocalUser({
email: "test@test.com",
@ -87,15 +87,17 @@ afterAll(async () => {
describe("API Tests", () => {
describe("POST /api/v1/accounts/:id", () => {
test("should return a 404 error when trying to fetch a non-existent user", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/999999`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl("/api/v1/accounts/999999", base_url),
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(404);
@ -107,18 +109,23 @@ describe("API Tests", () => {
describe("PATCH /api/v1/accounts/update_credentials", () => {
test("should update the authenticated user's display name", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/update_credentials`,
{
method: "PATCH",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
display_name: "New Display Name",
}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
"/api/v1/accounts/update_credentials",
base_url
),
{
method: "PATCH",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
display_name: "New Display Name",
}),
}
)
);
expect(response.status).toBe(200);
@ -134,15 +141,20 @@ describe("API Tests", () => {
describe("GET /api/v1/accounts/verify_credentials", () => {
test("should return the authenticated user's account information", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/verify_credentials`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
"/api/v1/accounts/verify_credentials",
base_url
),
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -179,15 +191,20 @@ describe("API Tests", () => {
describe("GET /api/v1/accounts/:id/statuses", () => {
test("should return the statuses of the specified user", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user.id}/statuses`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user.id}/statuses`,
base_url
),
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -203,16 +220,21 @@ describe("API Tests", () => {
describe("POST /api/v1/accounts/:id/follow", () => {
test("should follow the specified user and return an APIRelationship object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/follow`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/follow`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
)
);
expect(response.status).toBe(200);
@ -229,16 +251,21 @@ describe("API Tests", () => {
describe("POST /api/v1/accounts/:id/unfollow", () => {
test("should unfollow the specified user and return an APIRelationship object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/unfollow`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/unfollow`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
)
);
expect(response.status).toBe(200);
@ -255,16 +282,21 @@ describe("API Tests", () => {
describe("POST /api/v1/accounts/:id/remove_from_followers", () => {
test("should remove the specified user from the authenticated user's followers and return an APIRelationship object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/remove_from_followers`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/remove_from_followers`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
)
);
expect(response.status).toBe(200);
@ -281,16 +313,21 @@ describe("API Tests", () => {
describe("POST /api/v1/accounts/:id/block", () => {
test("should block the specified user and return an APIRelationship object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/block`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/block`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
)
);
expect(response.status).toBe(200);
@ -307,14 +344,13 @@ describe("API Tests", () => {
describe("GET /api/v1/blocks", () => {
test("should return an array of APIAccount objects for the user's blocked accounts", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/blocks`,
{
const response = await sendTestRequest(
new Request(wrapRelativeUrl("/api/v1/blocks", base_url), {
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
})
);
expect(response.status).toBe(200);
@ -331,16 +367,21 @@ describe("API Tests", () => {
describe("POST /api/v1/accounts/:id/unblock", () => {
test("should unblock the specified user and return an APIRelationship object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/unblock`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/unblock`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
)
);
expect(response.status).toBe(200);
@ -357,16 +398,21 @@ describe("API Tests", () => {
describe("POST /api/v1/accounts/:id/mute with notifications parameter", () => {
test("should mute the specified user and return an APIRelationship object with notifications set to false", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/mute`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ notifications: true }),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/mute`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ notifications: true }),
}
)
);
expect(response.status).toBe(200);
@ -382,16 +428,21 @@ describe("API Tests", () => {
});
test("should mute the specified user and return an APIRelationship object with notifications set to true", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/mute`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ notifications: false }),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/mute`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ notifications: false }),
}
)
);
expect(response.status).toBe(200);
@ -409,14 +460,13 @@ describe("API Tests", () => {
describe("GET /api/v1/mutes", () => {
test("should return an array of APIAccount objects for the user's muted accounts", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/mutes`,
{
const response = await sendTestRequest(
new Request(wrapRelativeUrl("/api/v1/mutes", base_url), {
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
})
);
expect(response.status).toBe(200);
@ -434,16 +484,21 @@ describe("API Tests", () => {
describe("POST /api/v1/accounts/:id/unmute", () => {
test("should unmute the specified user and return an APIRelationship object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/unmute`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/unmute`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
)
);
expect(response.status).toBe(200);
@ -460,16 +515,21 @@ describe("API Tests", () => {
describe("POST /api/v1/accounts/:id/pin", () => {
test("should pin the specified user and return an APIRelationship object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/pin`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/pin`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
)
);
expect(response.status).toBe(200);
@ -486,16 +546,21 @@ describe("API Tests", () => {
describe("POST /api/v1/accounts/:id/unpin", () => {
test("should unpin the specified user and return an APIRelationship object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/unpin`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/unpin`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
)
);
expect(response.status).toBe(200);
@ -512,16 +577,21 @@ describe("API Tests", () => {
describe("POST /api/v1/accounts/:id/note", () => {
test("should update the specified account's note and return the updated account object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/note`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ comment: "This is a new note" }),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/note`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ comment: "This is a new note" }),
}
)
);
expect(response.status).toBe(200);
@ -538,14 +608,19 @@ describe("API Tests", () => {
describe("GET /api/v1/accounts/relationships", () => {
test("should return an array of APIRelationship objects for the authenticated user's relationships", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/relationships?id[]=${user2.id}`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/relationships?id[]=${user2.id}`,
base_url
),
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
)
);
expect(response.status).toBe(200);
@ -571,15 +646,17 @@ describe("API Tests", () => {
describe("DELETE /api/v1/profile/avatar", () => {
test("should delete the avatar of the authenticated user and return the updated account object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/profile/avatar`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl("/api/v1/profile/avatar", base_url),
{
method: "DELETE",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -596,15 +673,17 @@ describe("API Tests", () => {
describe("DELETE /api/v1/profile/header", () => {
test("should delete the header of the authenticated user and return the updated account object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/profile/header`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl("/api/v1/profile/header", base_url),
{
method: "DELETE",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -621,16 +700,21 @@ describe("API Tests", () => {
describe("GET /api/v1/accounts/familiar_followers", () => {
test("should follow the user", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user2.id}/follow`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/${user2.id}/follow`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
}
)
);
expect(response.status).toBe(200);
@ -640,14 +724,19 @@ describe("API Tests", () => {
});
test("should return an array of objects with id and accounts properties, where id is a string and accounts is an array of APIAccount objects", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/familiar_followers?id[]=${user2.id}`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/api/v1/accounts/familiar_followers?id[]=${user2.id}`,
base_url
),
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
)
);
expect(response.status).toBe(200);

View file

@ -1,6 +1,3 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { getConfig } from "~classes/configmanager";
import type { Token } from "@prisma/client";
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import { client } from "~database/datasource";
@ -13,8 +10,11 @@ import type { APIAccount } from "~types/entities/account";
import type { APIAsyncAttachment } from "~types/entities/async_attachment";
import type { APIContext } from "~types/entities/context";
import type { APIStatus } from "~types/entities/status";
import { ConfigManager } from "config-manager";
import { sendTestRequest, wrapRelativeUrl } from "~tests/utils";
const config = getConfig();
const config = await new ConfigManager({}).getConfig();
const base_url = config.http.base_url;
let token: Token;
let user: UserWithRelations;
@ -86,15 +86,17 @@ describe("API Tests", () => {
const formData = new FormData();
formData.append("file", new Blob(["test"], { type: "text/plain" }));
const response = await fetch(
`${config.http.base_url}/api/v2/media`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
body: formData,
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(`${base_url}/api/v2/media`, base_url),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
body: formData,
}
)
);
expect(response.status).toBe(202);
@ -112,20 +114,22 @@ describe("API Tests", () => {
describe("POST /api/v1/statuses", () => {
test("should create a new status and return an APIStatus object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/statuses`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
status: "Hello, world!",
visibility: "public",
media_ids: [media1?.id],
}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(`${base_url}/api/v1/statuses`, base_url),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
status: "Hello, world!",
visibility: "public",
media_ids: [media1?.id],
}),
}
)
);
expect(response.status).toBe(200);
@ -158,20 +162,22 @@ describe("API Tests", () => {
});
test("should create a new status in reply to the previous one", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/statuses`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
status: "This is a reply!",
visibility: "public",
in_reply_to_id: status?.id,
}),
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(`${base_url}/api/v1/statuses`, base_url),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
status: "This is a reply!",
visibility: "public",
in_reply_to_id: status?.id,
}),
}
)
);
expect(response.status).toBe(200);
@ -206,14 +212,20 @@ describe("API Tests", () => {
describe("GET /api/v1/statuses/:id", () => {
test("should return the specified status object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/statuses/${status?.id}`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`${base_url}/api/v1/statuses/${status?.id}`,
base_url
),
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -251,15 +263,20 @@ describe("API Tests", () => {
describe("POST /api/v1/statuses/:id/reblog", () => {
test("should reblog the specified status and return the reblogged status object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/statuses/${status?.id}/reblog`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`${base_url}/api/v1/statuses/${status?.id}/reblog`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -277,15 +294,20 @@ describe("API Tests", () => {
describe("POST /api/v1/statuses/:id/unreblog", () => {
test("should unreblog the specified status and return the original status object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/statuses/${status?.id}/unreblog`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`${base_url}/api/v1/statuses/${status?.id}/unreblog`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -302,15 +324,20 @@ describe("API Tests", () => {
describe("GET /api/v1/statuses/:id/context", () => {
test("should return the context of the specified status", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/statuses/${status?.id}/context`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`${base_url}/api/v1/statuses/${status?.id}/context`,
base_url
),
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -330,14 +357,20 @@ describe("API Tests", () => {
describe("GET /api/v1/timelines/public", () => {
test("should return an array of APIStatus objects that includes the created status", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/timelines/public`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`${base_url}/api/v1/timelines/public`,
base_url
),
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -353,15 +386,20 @@ describe("API Tests", () => {
describe("GET /api/v1/accounts/:id/statuses", () => {
test("should return the statuses of the specified user", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/accounts/${user.id}/statuses`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`${base_url}/api/v1/accounts/${user.id}/statuses`,
base_url
),
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -384,14 +422,20 @@ describe("API Tests", () => {
describe("POST /api/v1/statuses/:id/favourite", () => {
test("should favourite the specified status object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/statuses/${status?.id}/favourite`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`${base_url}/api/v1/statuses/${status?.id}/favourite`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -400,14 +444,20 @@ describe("API Tests", () => {
describe("GET /api/v1/statuses/:id/favourited_by", () => {
test("should return an array of User objects who favourited the specified status", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/statuses/${status?.id}/favourited_by`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`${base_url}/api/v1/statuses/${status?.id}/favourited_by`,
base_url
),
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -425,14 +475,20 @@ describe("API Tests", () => {
describe("POST /api/v1/statuses/:id/unfavourite", () => {
test("should unfavourite the specified status object", async () => {
// Unfavourite the status
const response = await fetch(
`${config.http.base_url}/api/v1/statuses/${status?.id}/unfavourite`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`${base_url}/api/v1/statuses/${status?.id}/unfavourite`,
base_url
),
{
method: "POST",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
)
);
expect(response.status).toBe(200);
@ -449,14 +505,19 @@ describe("API Tests", () => {
describe("DELETE /api/v1/statuses/:id", () => {
test("should delete the specified status object", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/statuses/${status?.id}`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`${base_url}/api/v1/statuses/${status?.id}`,
base_url
),
{
method: "DELETE",
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
)
);
expect(response.status).toBe(200);

View file

@ -1,24 +0,0 @@
/* import { afterAll, beforeAll, describe, expect, it } from "bun:test";
import { AppDataSource } from "~database/datasource";
import { Instance } from "~database/entities/Instance";
let instance: Instance;
beforeAll(async () => {
if (!AppDataSource.isInitialized) await AppDataSource.initialize();
});
describe("Instance", () => {
it("should add an instance to the database if it doesn't already exist", async () => {
const url = "https://mastodon.social";
instance = await Instance.addIfNotExists(url);
expect(instance.base_url).toBe("mastodon.social");
});
});
afterAll(async () => {
await instance.remove();
await AppDataSource.destroy();
});
*/

View file

@ -1,99 +0,0 @@
import { type ConfigType, getConfig } from "~classes/configmanager";
import { afterAll, beforeAll, describe, expect, it } from "bun:test";
import { LocalBackend, S3Backend } from "~classes/media";
import { unlink } from "fs/promises";
import { DeleteObjectCommand } from "@aws-sdk/client-s3";
const originalConfig = getConfig();
const modifiedConfig: ConfigType = {
...originalConfig,
media: {
...originalConfig.media,
conversion: {
...originalConfig.media.conversion,
convert_images: false,
},
},
};
describe("LocalBackend", () => {
let localBackend: LocalBackend;
let fileName: string;
beforeAll(() => {
localBackend = new LocalBackend(modifiedConfig);
});
afterAll(async () => {
await unlink(`${process.cwd()}/uploads/${fileName}`);
});
describe("addMedia", () => {
it("should write the file to the local filesystem and return the hash", async () => {
const media = new File(["test"], "test.txt", {
type: "text/plain",
});
const hash = await localBackend.addMedia(media);
fileName = hash;
expect(hash).toBeDefined();
});
});
describe("getMediaByHash", () => {
it("should retrieve the file from the local filesystem and return it as a File object", async () => {
const media = await localBackend.getMediaByHash(fileName);
expect(media).toBeInstanceOf(File);
});
it("should return null if the file does not exist", async () => {
const media =
await localBackend.getMediaByHash("does-not-exist.txt");
expect(media).toBeNull();
});
});
});
describe("S3Backend", () => {
const s3Backend = new S3Backend(modifiedConfig);
let fileName: string;
afterAll(async () => {
const command = new DeleteObjectCommand({
Bucket: modifiedConfig.s3.bucket_name,
Key: fileName,
});
await s3Backend.client.send(command);
});
describe("addMedia", () => {
it("should write the file to the S3 bucket and return the hash", async () => {
const media = new File(["test"], "test.txt", {
type: "text/plain",
});
const hash = await s3Backend.addMedia(media);
fileName = hash;
expect(hash).toBeDefined();
});
});
describe("getMediaByHash", () => {
it("should retrieve the file from the S3 bucket and return it as a File object", async () => {
const media = await s3Backend.getMediaByHash(fileName);
expect(media).toBeInstanceOf(File);
});
it("should return null if the file does not exist", async () => {
const media = await s3Backend.getMediaByHash("does-not-exist.txt");
expect(media).toBeNull();
});
});
});

View file

@ -1 +0,0 @@
// Empty file

View file

@ -1,10 +1,11 @@
import { getConfig } from "~classes/configmanager";
import type { Application, Token } from "@prisma/client";
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import { client } from "~database/datasource";
import { createNewLocalUser } from "~database/entities/User";
import { sendTestRequest, wrapRelativeUrl } from "./utils";
const config = getConfig();
// const config = await new ConfigManager({}).getConfig();
const base_url = "http://lysand.localhost:8080"; //config.http.base_url;
let client_id: string;
let client_secret: string;
@ -30,10 +31,12 @@ describe("POST /api/v1/apps/", () => {
formData.append("redirect_uris", "https://example.com");
formData.append("scopes", "read write");
const response = await fetch(`${config.http.base_url}/api/v1/apps/`, {
method: "POST",
body: formData,
});
const response = await sendTestRequest(
new Request(wrapRelativeUrl("/api/v1/apps/", base_url), {
method: "POST",
body: formData,
})
);
expect(response.status).toBe(200);
expect(response.headers.get("content-type")).toBe("application/json");
@ -65,14 +68,19 @@ describe("POST /auth/login/", () => {
formData.append("email", "test@test.com");
formData.append("password", "test");
const response = await fetch(
`${config.http.base_url}/auth/login/?client_id=${client_id}&redirect_uri=https://example.com&response_type=code&scope=read+write`,
{
method: "POST",
body: formData,
redirect: "manual",
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl(
`/auth/login/?client_id=${client_id}&redirect_uri=https://example.com&response_type=code&scope=read+write`,
base_url
),
{
method: "POST",
body: formData,
}
)
);
expect(response.status).toBe(302);
expect(response.headers.get("Location")).toMatch(
/https:\/\/example.com\?code=/
@ -94,11 +102,12 @@ describe("POST /oauth/token/", () => {
formData.append("client_secret", client_secret);
formData.append("scope", "read+write");
const response = await fetch(`${config.http.base_url}/oauth/token/`, {
method: "POST",
// Do not set the Content-Type header for some reason
body: formData,
});
const response = await sendTestRequest(
new Request(wrapRelativeUrl("/oauth/token/", base_url), {
method: "POST",
body: formData,
})
);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const json = await response.json();
@ -119,15 +128,15 @@ describe("POST /oauth/token/", () => {
describe("GET /api/v1/apps/verify_credentials", () => {
test("should return the authenticated application's credentials", async () => {
const response = await fetch(
`${config.http.base_url}/api/v1/apps/verify_credentials`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token.access_token}`,
"Content-Type": "application/json",
},
}
const response = await sendTestRequest(
new Request(
wrapRelativeUrl("/api/v1/apps/verify_credentials", base_url),
{
headers: {
Authorization: `Bearer ${token.access_token}`,
},
}
)
);
expect(response.status).toBe(200);

15
tests/utils.ts Normal file
View file

@ -0,0 +1,15 @@
import { server } from "~index";
/**
* This allows us to send a test request to the server even when it isnt running
* CURRENTLY NOT WORKING, NEEDS TO BE FIXED
* @param req Request to send
* @returns Response from the server
*/
export async function sendTestRequest(req: Request) {
return server.fetch(req);
}
export function wrapRelativeUrl(url: string, base_url: string) {
return new URL(url, base_url);
}