This repository has been archived on 2022-08-14. You can view files and clone it, but cannot push or open issues or pull requests.
outline/server/routes/api/hooks.test.js

335 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* eslint-disable flowtype/require-valid-file-annotation */
import TestServer from "fetch-test-server";
import { IntegrationAuthentication, SearchQuery } from "../../models";
import webService from "../../services/web";
import { buildDocument, buildIntegration } from "../../test/factories";
import { flushdb, seed } from "../../test/support";
import * as Slack from "../../utils/slack";
const app = webService();
const server = new TestServer(app.callback());
beforeEach(() => flushdb());
afterAll(() => server.close());
jest.mock("../../utils/slack", () => ({
post: jest.fn(),
}));
describe("#hooks.unfurl", () => {
it("should return documents", async () => {
const { user, document } = await seed();
await IntegrationAuthentication.create({
service: "slack",
userId: user.id,
teamId: user.teamId,
token: "",
});
const res = await server.post("/api/hooks.unfurl", {
body: {
token: process.env.SLACK_VERIFICATION_TOKEN,
team_id: "TXXXXXXXX",
api_app_id: "AXXXXXXXXX",
event: {
type: "link_shared",
channel: "Cxxxxxx",
user: user.authentications[0].providerId,
message_ts: "123456789.9875",
links: [
{
domain: "getoutline.com",
url: document.url,
},
],
},
},
});
expect(res.status).toEqual(200);
expect(Slack.post).toHaveBeenCalled();
});
});
describe("#hooks.slack", () => {
it("should return no matches", async () => {
const { user, team } = await seed();
const res = await server.post("/api/hooks.slack", {
body: {
token: process.env.SLACK_VERIFICATION_TOKEN,
user_id: user.authentications[0].providerId,
team_id: team.authenticationProviders[0].providerId,
text: "dsfkndfskndsfkn",
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.attachments).toEqual(undefined);
});
it("should return search results with summary if query is in title", async () => {
const { user, team } = await seed();
const document = await buildDocument({
title: "This title contains a search term",
userId: user.id,
teamId: user.teamId,
});
const res = await server.post("/api/hooks.slack", {
body: {
token: process.env.SLACK_VERIFICATION_TOKEN,
user_id: user.authentications[0].providerId,
team_id: team.authenticationProviders[0].providerId,
text: "contains",
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.attachments.length).toEqual(1);
expect(body.attachments[0].title).toEqual(document.title);
expect(body.attachments[0].text).toEqual(document.getSummary());
});
it("should return search results if query is regex-like", async () => {
const { user, team } = await seed();
await buildDocument({
title: "This title contains a search term",
userId: user.id,
teamId: user.teamId,
});
const res = await server.post("/api/hooks.slack", {
body: {
token: process.env.SLACK_VERIFICATION_TOKEN,
user_id: user.authentications[0].providerId,
team_id: team.authenticationProviders[0].providerId,
text: "*contains",
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.attachments.length).toEqual(1);
});
it("should return search results with snippet if query is in text", async () => {
const { user, team } = await seed();
const document = await buildDocument({
text: "This title contains a search term",
userId: user.id,
teamId: user.teamId,
});
const res = await server.post("/api/hooks.slack", {
body: {
token: process.env.SLACK_VERIFICATION_TOKEN,
user_id: user.authentications[0].providerId,
team_id: team.authenticationProviders[0].providerId,
text: "contains",
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.attachments.length).toEqual(1);
expect(body.attachments[0].title).toEqual(document.title);
expect(body.attachments[0].text).toEqual(
"This title *contains* a search term"
);
});
it("should save search term, hits and source", async (done) => {
const { user, team } = await seed();
await server.post("/api/hooks.slack", {
body: {
token: process.env.SLACK_VERIFICATION_TOKEN,
user_id: user.authentications[0].providerId,
team_id: team.authenticationProviders[0].providerId,
text: "contains",
},
});
// setTimeout is needed here because SearchQuery is saved asynchronously
// in order to not slow down the response time.
setTimeout(async () => {
const searchQuery = await SearchQuery.findAll({
where: { query: "contains" },
});
expect(searchQuery.length).toBe(1);
expect(searchQuery[0].results).toBe(0);
expect(searchQuery[0].source).toBe("slack");
done();
}, 100);
});
it("should respond with help content for help keyword", async () => {
const { user, team } = await seed();
const res = await server.post("/api/hooks.slack", {
body: {
token: process.env.SLACK_VERIFICATION_TOKEN,
user_id: user.authentications[0].providerId,
team_id: team.authenticationProviders[0].providerId,
text: "help",
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.text.includes("How to use")).toEqual(true);
});
it("should respond with help content for no keyword", async () => {
const { user, team } = await seed();
const res = await server.post("/api/hooks.slack", {
body: {
token: process.env.SLACK_VERIFICATION_TOKEN,
user_id: user.authentications[0].providerId,
team_id: team.authenticationProviders[0].providerId,
text: "",
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.text.includes("How to use")).toEqual(true);
});
it("should return search results with snippet for unknown user", async () => {
const { user, team } = await seed();
// unpublished document will not be returned
await buildDocument({
text: "This title contains a search term",
userId: user.id,
teamId: user.teamId,
publishedAt: null,
});
const document = await buildDocument({
text: "This title contains a search term",
userId: user.id,
teamId: user.teamId,
});
const res = await server.post("/api/hooks.slack", {
body: {
token: process.env.SLACK_VERIFICATION_TOKEN,
user_id: "unknown-slack-user-id",
team_id: team.authenticationProviders[0].providerId,
text: "contains",
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.text).toContain("you havent signed in to Outline yet");
expect(body.attachments.length).toEqual(1);
expect(body.attachments[0].title).toEqual(document.title);
expect(body.attachments[0].text).toEqual(
"This title *contains* a search term"
);
});
it("should return search results with snippet for user through integration mapping", async () => {
const { user } = await seed();
const serviceTeamId = "slack_team_id";
await buildIntegration({
teamId: user.teamId,
settings: {
serviceTeamId,
},
});
const document = await buildDocument({
text: "This title contains a search term",
userId: user.id,
teamId: user.teamId,
});
const res = await server.post("/api/hooks.slack", {
body: {
token: process.env.SLACK_VERIFICATION_TOKEN,
user_id: "unknown-slack-user-id",
team_id: serviceTeamId,
text: "contains",
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.text).toContain("you havent signed in to Outline yet");
expect(body.attachments.length).toEqual(1);
expect(body.attachments[0].title).toEqual(document.title);
expect(body.attachments[0].text).toEqual(
"This title *contains* a search term"
);
});
it("should error if incorrect verification token", async () => {
const { user, team } = await seed();
const res = await server.post("/api/hooks.slack", {
body: {
token: "wrong-verification-token",
user_id: user.authentications[0].providerId,
team_id: team.authenticationProviders[0].providerId,
text: "Welcome",
},
});
expect(res.status).toEqual(401);
});
});
describe("#hooks.interactive", () => {
it("should respond with replacement message", async () => {
const { user, team } = await seed();
const document = await buildDocument({
title: "This title contains a search term",
userId: user.id,
teamId: user.teamId,
});
const payload = JSON.stringify({
token: process.env.SLACK_VERIFICATION_TOKEN,
user: { id: user.authentications[0].providerId },
team: { id: team.authenticationProviders[0].providerId },
callback_id: document.id,
});
const res = await server.post("/api/hooks.interactive", {
body: { payload },
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.response_type).toEqual("in_channel");
expect(body.attachments.length).toEqual(1);
expect(body.attachments[0].title).toEqual(document.title);
});
it("should respond with replacement message if unknown user", async () => {
const { user, team } = await seed();
const document = await buildDocument({
title: "This title contains a search term",
userId: user.id,
teamId: user.teamId,
});
const payload = JSON.stringify({
token: process.env.SLACK_VERIFICATION_TOKEN,
user: { id: "unknown-slack-user-id" },
team: { id: team.authenticationProviders[0].providerId },
callback_id: document.id,
});
const res = await server.post("/api/hooks.interactive", {
body: { payload },
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.response_type).toEqual("in_channel");
expect(body.attachments.length).toEqual(1);
expect(body.attachments[0].title).toEqual(document.title);
});
it("should error if incorrect verification token", async () => {
const { user } = await seed();
const payload = JSON.stringify({
token: "wrong-verification-token",
user: { id: user.authentications[0].providerId, name: user.name },
callback_id: "doesnt-matter",
});
const res = await server.post("/api/hooks.interactive", {
body: { payload },
});
expect(res.status).toEqual(401);
});
});