mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
333 lines
9.6 KiB
TypeScript
333 lines
9.6 KiB
TypeScript
import env from "@server/env";
|
|
import {
|
|
buildAdmin,
|
|
buildUser,
|
|
buildWebhookSubscription,
|
|
} from "@server/test/factories";
|
|
import { getTestServer } from "@server/test/support";
|
|
|
|
const server = getTestServer();
|
|
|
|
describe("#webhookSubscriptions.list", () => {
|
|
it("should fail with status 401 unauthorized when user token is missing", async () => {
|
|
const res = await server.post("/api/webhookSubscriptions.list", {
|
|
body: {},
|
|
});
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(401);
|
|
expect(body.message).toEqual("Authentication required");
|
|
});
|
|
|
|
it("should fail with status 403 forbidden for non-admin user", async () => {
|
|
const user = await buildUser();
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.list", user);
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(403);
|
|
expect(body.message).toEqual("Admin role required");
|
|
});
|
|
|
|
it("should return the webhook subscriptions for the user's team", async () => {
|
|
const user = await buildAdmin();
|
|
const webhookSubscriptions = await Promise.all(
|
|
Array(20)
|
|
.fill(1)
|
|
.map(() =>
|
|
buildWebhookSubscription({
|
|
createdById: user.id,
|
|
teamId: user.teamId,
|
|
})
|
|
)
|
|
);
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.list", user);
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(200);
|
|
expect(body.data.length).toEqual(webhookSubscriptions.length);
|
|
});
|
|
|
|
it("should filter webhook subscriptions by query", async () => {
|
|
const user = await buildAdmin();
|
|
await buildWebhookSubscription({
|
|
createdById: user.id,
|
|
teamId: user.teamId,
|
|
name: "Production Webhook",
|
|
});
|
|
await buildWebhookSubscription({
|
|
createdById: user.id,
|
|
teamId: user.teamId,
|
|
name: "Staging Webhook",
|
|
});
|
|
await buildWebhookSubscription({
|
|
createdById: user.id,
|
|
teamId: user.teamId,
|
|
name: "Development Hook",
|
|
});
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.list", user, {
|
|
body: { query: "webhook" },
|
|
});
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(200);
|
|
expect(body.data.length).toEqual(2);
|
|
expect(
|
|
body.data.every((webhook: { name: string }) =>
|
|
webhook.name.toLowerCase().includes("webhook")
|
|
)
|
|
).toBe(true);
|
|
});
|
|
|
|
it("should filter webhook subscriptions by query case-insensitively", async () => {
|
|
const user = await buildAdmin();
|
|
await buildWebhookSubscription({
|
|
createdById: user.id,
|
|
teamId: user.teamId,
|
|
name: "Production Webhook",
|
|
});
|
|
await buildWebhookSubscription({
|
|
createdById: user.id,
|
|
teamId: user.teamId,
|
|
name: "Staging Webhook",
|
|
});
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.list", user, {
|
|
body: { query: "PRODUCTION" },
|
|
});
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(200);
|
|
expect(body.data.length).toEqual(1);
|
|
expect(body.data[0].name).toEqual("Production Webhook");
|
|
});
|
|
|
|
it("should return empty array when query matches no webhook subscriptions", async () => {
|
|
const user = await buildAdmin();
|
|
await buildWebhookSubscription({
|
|
createdById: user.id,
|
|
teamId: user.teamId,
|
|
name: "Production Webhook",
|
|
});
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.list", user, {
|
|
body: { query: "nonexistent" },
|
|
});
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(200);
|
|
expect(body.data.length).toEqual(0);
|
|
});
|
|
});
|
|
|
|
describe("#webhookSubscriptions.create", () => {
|
|
it("should fail with status 401 unauthorized when user token is missing", async () => {
|
|
const res = await server.post("/api/webhookSubscriptions.create", {
|
|
body: {},
|
|
});
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(401);
|
|
expect(body.message).toEqual("Authentication required");
|
|
});
|
|
|
|
it("should fail with status 403 forbidden for non-admin user", async () => {
|
|
const user = await buildUser();
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.create", user);
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(403);
|
|
expect(body.message).toEqual("Admin role required");
|
|
});
|
|
|
|
it("should successfully create a webhook subscription", async () => {
|
|
const user = await buildAdmin();
|
|
const name = "Test webhook";
|
|
const url = "https://www.example.com";
|
|
const events = ["comments"];
|
|
const secret = "Test secret";
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.create", user, {
|
|
body: {
|
|
name,
|
|
url,
|
|
events,
|
|
secret,
|
|
},
|
|
});
|
|
const body = await res.json();
|
|
const webhook = body.data;
|
|
|
|
expect(res.status).toEqual(200);
|
|
expect(webhook.name).toEqual(name);
|
|
expect(webhook.url).toEqual(url);
|
|
expect(webhook.events).toEqual(events);
|
|
expect(webhook.secret).toEqual(secret);
|
|
expect(webhook.enabled).toEqual(true);
|
|
});
|
|
|
|
it("should reject http urls when cloud hosted", async () => {
|
|
vi.spyOn(env, "isCloudHosted", "get").mockReturnValue(true);
|
|
|
|
const user = await buildAdmin();
|
|
const res = await server.post("/api/webhookSubscriptions.create", user, {
|
|
body: {
|
|
name: "Test webhook",
|
|
url: "http://www.example.com",
|
|
events: ["comments"],
|
|
},
|
|
});
|
|
|
|
expect(res.status).toEqual(400);
|
|
});
|
|
|
|
it("should allow http urls when not cloud hosted", async () => {
|
|
vi.spyOn(env, "isCloudHosted", "get").mockReturnValue(false);
|
|
|
|
const user = await buildAdmin();
|
|
const url = "http://www.example.com";
|
|
const res = await server.post("/api/webhookSubscriptions.create", user, {
|
|
body: {
|
|
name: "Test webhook",
|
|
url,
|
|
events: ["comments"],
|
|
},
|
|
});
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(200);
|
|
expect(body.data.url).toEqual(url);
|
|
});
|
|
});
|
|
|
|
describe("#webhookSubscriptions.update", () => {
|
|
it("should fail with status 401 unauthorized when user token is missing", async () => {
|
|
const res = await server.post("/api/webhookSubscriptions.update", {
|
|
body: {},
|
|
});
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(401);
|
|
expect(body.message).toEqual("Authentication required");
|
|
});
|
|
|
|
it("should fail with status 403 forbidden for non-admin user", async () => {
|
|
const user = await buildUser();
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.update", user);
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(403);
|
|
expect(body.message).toEqual("Admin role required");
|
|
});
|
|
|
|
it("should successfully update a webhook subscription", async () => {
|
|
const user = await buildAdmin();
|
|
const name = "Updated webhook name";
|
|
const url = "https://www.example.com/update";
|
|
const events = ["comments"];
|
|
|
|
const existingWebhook = await buildWebhookSubscription({
|
|
name: "Created webhook name",
|
|
url: "https://www.example.com/create",
|
|
events: ["*"],
|
|
createdById: user.id,
|
|
teamId: user.teamId,
|
|
});
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.update", user, {
|
|
body: {
|
|
id: existingWebhook.id,
|
|
name,
|
|
url,
|
|
events,
|
|
},
|
|
});
|
|
const body = await res.json();
|
|
const webhook = body.data;
|
|
|
|
expect(res.status).toEqual(200);
|
|
expect(webhook.name).toEqual(name);
|
|
expect(webhook.url).toEqual(url);
|
|
expect(webhook.events).toEqual(events);
|
|
expect(webhook.enabled).toEqual(true);
|
|
});
|
|
|
|
it("should activate a disabled webhook subscription when it's updated", async () => {
|
|
const user = await buildAdmin();
|
|
const name = "Updated webhook name";
|
|
const url = "https://www.example.com/update";
|
|
const events = ["comments"];
|
|
|
|
const disabledWebhook = await buildWebhookSubscription({
|
|
name: "Created webhook name",
|
|
url: "https://www.example.com/create",
|
|
events: ["*"],
|
|
createdById: user.id,
|
|
teamId: user.teamId,
|
|
enabled: false,
|
|
});
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.update", user, {
|
|
body: {
|
|
id: disabledWebhook.id,
|
|
name,
|
|
url,
|
|
events,
|
|
},
|
|
});
|
|
const body = await res.json();
|
|
const webhook = body.data;
|
|
|
|
expect(res.status).toEqual(200);
|
|
expect(webhook.name).toEqual(name);
|
|
expect(webhook.url).toEqual(url);
|
|
expect(webhook.events).toEqual(events);
|
|
expect(webhook.enabled).toEqual(true);
|
|
});
|
|
});
|
|
|
|
describe("#webhookSubscriptions.delete", () => {
|
|
it("should fail with status 401 unauthorized when user token is missing", async () => {
|
|
const res = await server.post("/api/webhookSubscriptions.delete", {
|
|
body: {},
|
|
});
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(401);
|
|
expect(body.message).toEqual("Authentication required");
|
|
});
|
|
|
|
it("should fail with status 403 forbidden for non-admin user", async () => {
|
|
const user = await buildUser();
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.delete", user);
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(403);
|
|
expect(body.message).toEqual("Admin role required");
|
|
});
|
|
|
|
it("should successfully delete a webhook subscription", async () => {
|
|
const user = await buildAdmin();
|
|
const createdWebhook = await buildWebhookSubscription({
|
|
name: "Test webhook",
|
|
url: "https://www.example.com",
|
|
events: ["*"],
|
|
createdById: user.id,
|
|
teamId: user.teamId,
|
|
});
|
|
|
|
const res = await server.post("/api/webhookSubscriptions.delete", user, {
|
|
body: { id: createdWebhook.id },
|
|
});
|
|
const body = await res.json();
|
|
|
|
expect(res.status).toEqual(200);
|
|
expect(body.success).toEqual(true);
|
|
});
|
|
});
|