build: use default node test runner for unit tests
This commit is contained in:
Generated
-119
@@ -26,9 +26,7 @@
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/markup-js": "^1.5.0",
|
||||
"@types/node": "^20.19.30",
|
||||
"@types/sinon": "^21.0.0",
|
||||
"@vercel/ncc": "^0.38.4",
|
||||
"sinon": "^21.0.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"engines": {
|
||||
@@ -386,47 +384,6 @@
|
||||
"@octokit/openapi-types": "^27.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sinonjs/commons": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
|
||||
"integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"type-detect": "4.0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sinonjs/fake-timers": {
|
||||
"version": "15.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.0.tgz",
|
||||
"integrity": "sha512-cqfapCxwTGsrR80FEgOoPsTonoefMBY7dnUEbQ+GRcved0jvkJLzvX6F4WtN+HBqbPX/SiFsIRUp+IrCW/2I2w==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@sinonjs/commons": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@sinonjs/samsam": {
|
||||
"version": "8.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz",
|
||||
"integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@sinonjs/commons": "^3.0.1",
|
||||
"type-detect": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sinonjs/samsam/node_modules/type-detect": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
|
||||
"integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@slack/logger": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@slack/logger/-/logger-4.0.0.tgz",
|
||||
@@ -510,23 +467,6 @@
|
||||
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/sinon": {
|
||||
"version": "21.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-21.0.0.tgz",
|
||||
"integrity": "sha512-+oHKZ0lTI+WVLxx1IbJDNmReQaIsQJjN2e7UUrJHEeByG7bFeKJYsv1E75JxTQ9QKJDp21bAa/0W2Xo4srsDnw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/sinonjs__fake-timers": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/sinonjs__fake-timers": {
|
||||
"version": "8.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz",
|
||||
"integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vercel/ncc": {
|
||||
"version": "0.38.4",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.38.4.tgz",
|
||||
@@ -634,16 +574,6 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/diff": {
|
||||
"version": "8.0.3",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz",
|
||||
"integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
@@ -830,15 +760,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
@@ -1043,36 +964,6 @@
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/sinon": {
|
||||
"version": "21.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.1.tgz",
|
||||
"integrity": "sha512-Z0NVCW45W8Mg5oC/27/+fCqIHFnW8kpkFOq0j9XJIev4Ld0mKmERaZv5DMLAb9fGCevjKwaEeIQz5+MBXfZcDw==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@sinonjs/commons": "^3.0.1",
|
||||
"@sinonjs/fake-timers": "^15.1.0",
|
||||
"@sinonjs/samsam": "^8.0.3",
|
||||
"diff": "^8.0.2",
|
||||
"supports-color": "^7.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/sinon"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
@@ -1082,16 +973,6 @@
|
||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/type-detect": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
|
||||
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
|
||||
@@ -51,9 +51,7 @@
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/markup-js": "^1.5.0",
|
||||
"@types/node": "^20.19.30",
|
||||
"@types/sinon": "^21.0.0",
|
||||
"@vercel/ncc": "^0.38.4",
|
||||
"sinon": "^21.0.1",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
|
||||
+308
-221
@@ -1,8 +1,7 @@
|
||||
import assert from "node:assert";
|
||||
import { beforeEach, describe, it } from "node:test";
|
||||
import { beforeEach, describe, it, mock } from "node:test";
|
||||
import webapi from "@slack/web-api";
|
||||
import errors from "@slack/web-api/dist/errors.js";
|
||||
import sinon from "sinon";
|
||||
import Client from "../src/client.js";
|
||||
import Config from "../src/config.js";
|
||||
import SlackError from "../src/errors.js";
|
||||
@@ -48,7 +47,10 @@ describe("client", () => {
|
||||
method: "chat.postMessage",
|
||||
},
|
||||
};
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example-001");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
token: "xoxb-example-001",
|
||||
};
|
||||
try {
|
||||
await new Client().post(config);
|
||||
assert.fail("Failed to throw for missing input");
|
||||
@@ -64,10 +66,13 @@ describe("client", () => {
|
||||
|
||||
describe("api", async () => {
|
||||
it("uses arguments to send to a slack api method", async () => {
|
||||
const apis = sinon.stub().resolves({ ok: true });
|
||||
const constructors = sinon
|
||||
.stub(mocks.webapi, "WebClient")
|
||||
.returns({ apiCall: apis });
|
||||
const apis = mock.fn(() => Promise.resolve({ ok: true }));
|
||||
const constructorCalls = [];
|
||||
// Use a regular function as constructor since mock.fn() doesn't work with `new`
|
||||
mocks.webapi.WebClient = function (...args) {
|
||||
constructorCalls.push(args);
|
||||
this.apiCall = apis;
|
||||
};
|
||||
/**
|
||||
* @type {Config}
|
||||
*/
|
||||
@@ -87,31 +92,40 @@ describe("client", () => {
|
||||
webapi: mocks.webapi,
|
||||
};
|
||||
await new Client().post(config);
|
||||
assert.ok(constructors.calledWithNew());
|
||||
assert.equal(constructorCalls.length, 1);
|
||||
const [token, options] = constructorCalls[0];
|
||||
assert.equal(token, "xoxb-example-002");
|
||||
assert.deepEqual(options, {
|
||||
agent: undefined,
|
||||
allowAbsoluteUrls: false,
|
||||
logger: config.logger,
|
||||
retryConfig: webapi.retryPolicies.fiveRetriesInFiveMinutes,
|
||||
slackApiUrl: undefined,
|
||||
});
|
||||
assert.equal(apis.mock.callCount(), 1);
|
||||
const [method, args] = apis.mock.calls[0].arguments;
|
||||
assert.equal(method, "pins.add");
|
||||
assert.deepEqual(args, {
|
||||
channel: "CHANNELHERE",
|
||||
timestamp: "1234567890.000000",
|
||||
});
|
||||
assert.ok(
|
||||
constructors.calledWith("xoxb-example-002", {
|
||||
agent: undefined,
|
||||
allowAbsoluteUrls: false,
|
||||
logger: config.logger,
|
||||
retryConfig: webapi.retryPolicies.fiveRetriesInFiveMinutes,
|
||||
slackApiUrl: undefined,
|
||||
}),
|
||||
mocks.core.setOutput.mock.calls.some(
|
||||
(c) => c.arguments[0] === "ok" && c.arguments[1] === true,
|
||||
),
|
||||
);
|
||||
assert.ok(apis.calledOnce);
|
||||
assert.ok(
|
||||
apis.calledWith("pins.add", {
|
||||
channel: "CHANNELHERE",
|
||||
timestamp: "1234567890.000000",
|
||||
}),
|
||||
);
|
||||
assert.ok(config.core.setOutput.calledWith("ok", true));
|
||||
});
|
||||
|
||||
it("uses arguments to send to a custom api method", async () => {
|
||||
const apis = sinon.stub().resolves({ done: true, response: "Infinite" });
|
||||
const constructors = sinon
|
||||
.stub(mocks.webapi, "WebClient")
|
||||
.returns({ apiCall: apis });
|
||||
const apis = mock.fn(() =>
|
||||
Promise.resolve({ done: true, response: "Infinite" }),
|
||||
);
|
||||
const constructorCalls = [];
|
||||
// Use a regular function as constructor since mock.fn() doesn't work with `new`
|
||||
mocks.webapi.WebClient = function (...args) {
|
||||
constructorCalls.push(args);
|
||||
this.apiCall = apis;
|
||||
};
|
||||
/**
|
||||
* @type {Config}
|
||||
*/
|
||||
@@ -134,29 +148,35 @@ describe("client", () => {
|
||||
webapi: mocks.webapi,
|
||||
};
|
||||
await new Client().post(config);
|
||||
assert.ok(constructors.calledWithNew());
|
||||
assert.equal(constructorCalls.length, 1);
|
||||
const [token, options] = constructorCalls[0];
|
||||
assert.equal(token, "ollamapassword");
|
||||
assert.deepEqual(options, {
|
||||
agent: undefined,
|
||||
allowAbsoluteUrls: false,
|
||||
logger: config.logger,
|
||||
retryConfig: webapi.retryPolicies.tenRetriesInAboutThirtyMinutes,
|
||||
slackApiUrl: "http://localhost:11434/api/",
|
||||
});
|
||||
assert.equal(apis.mock.callCount(), 1);
|
||||
const [method, args] = apis.mock.calls[0].arguments;
|
||||
assert.equal(method, "generate");
|
||||
assert.deepEqual(args, {
|
||||
model: "llama3.2",
|
||||
prompt: "How many sides does a circle have?",
|
||||
stream: false,
|
||||
});
|
||||
assert.ok(
|
||||
constructors.calledWith("ollamapassword", {
|
||||
agent: undefined,
|
||||
allowAbsoluteUrls: false,
|
||||
logger: config.logger,
|
||||
retryConfig: webapi.retryPolicies.tenRetriesInAboutThirtyMinutes,
|
||||
slackApiUrl: "http://localhost:11434/api/",
|
||||
}),
|
||||
mocks.core.setOutput.mock.calls.some(
|
||||
(c) => c.arguments[0] === "ok" && c.arguments[1] === undefined,
|
||||
),
|
||||
);
|
||||
assert.ok(apis.calledOnce);
|
||||
assert.ok(
|
||||
apis.calledWith("generate", {
|
||||
model: "llama3.2",
|
||||
prompt: "How many sides does a circle have?",
|
||||
stream: false,
|
||||
}),
|
||||
);
|
||||
assert.ok(config.core.setOutput.calledWith("ok", undefined));
|
||||
assert.ok(
|
||||
config.core.setOutput.calledWith(
|
||||
"response",
|
||||
JSON.stringify({ done: true, response: "Infinite" }),
|
||||
mocks.core.setOutput.mock.calls.some(
|
||||
(c) =>
|
||||
c.arguments[0] === "response" &&
|
||||
c.arguments[1] ===
|
||||
JSON.stringify({ done: true, response: "Infinite" }),
|
||||
),
|
||||
);
|
||||
});
|
||||
@@ -164,123 +184,150 @@ describe("client", () => {
|
||||
|
||||
describe("success", () => {
|
||||
it("calls 'chat.postMessage' with the given token and content", async () => {
|
||||
try {
|
||||
const args = {
|
||||
channel: "C0123456789",
|
||||
text: "hello",
|
||||
const args = {
|
||||
channel: "C0123456789",
|
||||
text: "hello",
|
||||
thread_ts: "1234567890.000001",
|
||||
};
|
||||
const response = {
|
||||
ok: true,
|
||||
channel: "C0123456789",
|
||||
ts: "1234567890.000002",
|
||||
message: {
|
||||
thread_ts: "1234567890.000001",
|
||||
};
|
||||
const response = {
|
||||
ok: true,
|
||||
channel: "C0123456789",
|
||||
ts: "1234567890.000002",
|
||||
message: {
|
||||
thread_ts: "1234567890.000001",
|
||||
},
|
||||
};
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.core.getInput.withArgs("payload").returns(JSON.stringify(args));
|
||||
mocks.calls.resolves(response);
|
||||
await send(mocks.core);
|
||||
assert.deepEqual(mocks.calls.getCall(0).firstArg, "chat.postMessage");
|
||||
assert.deepEqual(mocks.calls.getCall(0).lastArg, args);
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, true);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.equal(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
JSON.stringify(response),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(2).firstArg, "channel_id");
|
||||
assert.equal(mocks.core.setOutput.getCall(2).lastArg, "C0123456789");
|
||||
assert.equal(mocks.core.setOutput.getCall(3).firstArg, "thread_ts");
|
||||
assert.equal(
|
||||
mocks.core.setOutput.getCall(3).lastArg,
|
||||
"1234567890.000001",
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(4).firstArg, "ts");
|
||||
assert.equal(
|
||||
mocks.core.setOutput.getCall(4).lastArg,
|
||||
"1234567890.000002",
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(5).firstArg, "time");
|
||||
assert.equal(mocks.core.setOutput.getCalls().length, 6);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
assert.fail("Unexpected error when calling the method");
|
||||
}
|
||||
},
|
||||
};
|
||||
const payload = JSON.stringify(args);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
token: "xoxb-example",
|
||||
payload,
|
||||
};
|
||||
mocks.calls._resolvesWith = response;
|
||||
await send(mocks.core);
|
||||
assert.deepEqual(
|
||||
mocks.calls.mock.calls[0].arguments[0],
|
||||
"chat.postMessage",
|
||||
);
|
||||
assert.deepEqual(mocks.calls.mock.calls[0].arguments[1], args);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], true);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[0],
|
||||
"response",
|
||||
);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify(response),
|
||||
);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[2].arguments[0],
|
||||
"channel_id",
|
||||
);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[2].arguments[1],
|
||||
"C0123456789",
|
||||
);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[3].arguments[0],
|
||||
"thread_ts",
|
||||
);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[3].arguments[1],
|
||||
"1234567890.000001",
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[4].arguments[0], "ts");
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[4].arguments[1],
|
||||
"1234567890.000002",
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[5].arguments[0], "time");
|
||||
assert.equal(mocks.core.setOutput.mock.calls.length, 6);
|
||||
});
|
||||
|
||||
it("calls 'conversations.create' with the given token and content", async () => {
|
||||
try {
|
||||
const args = {
|
||||
const args = {
|
||||
name: "pull-request-review-010101",
|
||||
};
|
||||
const response = {
|
||||
ok: true,
|
||||
channel: {
|
||||
id: "C0101010101",
|
||||
name: "pull-request-review-010101",
|
||||
};
|
||||
const response = {
|
||||
ok: true,
|
||||
channel: {
|
||||
id: "C0101010101",
|
||||
name: "pull-request-review-010101",
|
||||
is_channel: true,
|
||||
created: 1730425428,
|
||||
},
|
||||
};
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.core.getInput.withArgs("payload").returns(JSON.stringify(args));
|
||||
mocks.calls.resolves(response);
|
||||
await send(mocks.core);
|
||||
assert.deepEqual(mocks.calls.getCall(0).firstArg, "chat.postMessage");
|
||||
assert.deepEqual(mocks.calls.getCall(0).lastArg, args);
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, true);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.equal(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
JSON.stringify(response),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(2).firstArg, "channel_id");
|
||||
assert.equal(mocks.core.setOutput.getCall(2).lastArg, "C0101010101");
|
||||
assert.equal(mocks.core.setOutput.getCall(3).firstArg, "time");
|
||||
assert.equal(mocks.core.setOutput.getCalls().length, 4);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
assert.fail("Unexpected error when calling the method");
|
||||
}
|
||||
is_channel: true,
|
||||
created: 1730425428,
|
||||
},
|
||||
};
|
||||
const payload = JSON.stringify(args);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
token: "xoxb-example",
|
||||
payload,
|
||||
};
|
||||
mocks.calls._resolvesWith = response;
|
||||
await send(mocks.core);
|
||||
assert.deepEqual(
|
||||
mocks.calls.mock.calls[0].arguments[0],
|
||||
"chat.postMessage",
|
||||
);
|
||||
assert.deepEqual(mocks.calls.mock.calls[0].arguments[1], args);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], true);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[0],
|
||||
"response",
|
||||
);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify(response),
|
||||
);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[2].arguments[0],
|
||||
"channel_id",
|
||||
);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[2].arguments[1],
|
||||
"C0101010101",
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[3].arguments[0], "time");
|
||||
assert.equal(mocks.core.setOutput.mock.calls.length, 4);
|
||||
});
|
||||
|
||||
it("calls 'files.uploadV2' with the provided token and content", async () => {
|
||||
try {
|
||||
const args = {
|
||||
channel: "C0000000001",
|
||||
initial_comment: "the results are in!",
|
||||
file: "results.out",
|
||||
filename: "results-888888.out",
|
||||
};
|
||||
const response = {
|
||||
ok: true,
|
||||
files: [{ id: "F0000000001", created: 1234567890 }],
|
||||
};
|
||||
mocks.core.getInput.withArgs("method").returns("files.uploadV2");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxp-example");
|
||||
mocks.core.getInput.withArgs("payload").returns(JSON.stringify(args));
|
||||
mocks.calls.resolves(response);
|
||||
await send(mocks.core);
|
||||
assert.deepEqual(mocks.calls.getCall(0).lastArg, args);
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, true);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.equal(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
JSON.stringify(response),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(2).firstArg, "time");
|
||||
assert.equal(mocks.core.setOutput.getCalls().length, 3);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
assert.fail("Unexpected error when calling the method");
|
||||
}
|
||||
const args = {
|
||||
channel: "C0000000001",
|
||||
initial_comment: "the results are in!",
|
||||
file: "results.out",
|
||||
filename: "results-888888.out",
|
||||
};
|
||||
const response = {
|
||||
ok: true,
|
||||
files: [{ id: "F0000000001", created: 1234567890 }],
|
||||
};
|
||||
const payload = JSON.stringify(args);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "files.uploadV2",
|
||||
token: "xoxp-example",
|
||||
payload,
|
||||
};
|
||||
mocks.calls._resolvesWith = response;
|
||||
await send(mocks.core);
|
||||
assert.deepEqual(mocks.calls.mock.calls[0].arguments[1], args);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], true);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[0],
|
||||
"response",
|
||||
);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify(response),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[2].arguments[0], "time");
|
||||
assert.equal(mocks.core.setOutput.mock.calls.length, 3);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -296,26 +343,34 @@ describe("client", () => {
|
||||
message: "Something bad happened!",
|
||||
},
|
||||
};
|
||||
mocks.booleanInputs = {
|
||||
...mocks.booleanInputs,
|
||||
errors: true,
|
||||
};
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
token: "xoxb-example",
|
||||
payload: `"text": "hello"`,
|
||||
};
|
||||
mocks.calls._rejectsWith = errors.requestErrorWithOriginal(response, true);
|
||||
try {
|
||||
mocks.core.getInput.reset();
|
||||
mocks.core.getBooleanInput.withArgs("errors").returns(true);
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.core.getInput.withArgs("payload").returns(`"text": "hello"`);
|
||||
mocks.calls.rejects(errors.requestErrorWithOriginal(response, true));
|
||||
await send(mocks.core);
|
||||
assert.fail("Expected an error but none was found");
|
||||
} catch (_err) {
|
||||
assert.ok(mocks.core.setFailed.called);
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, false);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.ok(mocks.core.setFailed.mock.callCount() > 0);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], false);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[0],
|
||||
"response",
|
||||
);
|
||||
assert.deepEqual(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify(response),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(2).firstArg, "time");
|
||||
assert.equal(mocks.core.setOutput.getCalls().length, 3);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[2].arguments[0], "time");
|
||||
assert.equal(mocks.core.setOutput.mock.calls.length, 3);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -333,26 +388,32 @@ describe("client", () => {
|
||||
error: "unknown_http_method",
|
||||
},
|
||||
};
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
token: "xoxb-example",
|
||||
payload: `"text": "hello"`,
|
||||
};
|
||||
mocks.calls._rejectsWith = errors.httpErrorFromResponse(response);
|
||||
try {
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.core.getInput.withArgs("payload").returns(`"text": "hello"`);
|
||||
mocks.calls.rejects(errors.httpErrorFromResponse(response));
|
||||
await send(mocks.core);
|
||||
assert.fail("Expected an error but none was found");
|
||||
} catch (_err) {
|
||||
assert.strictEqual(mocks.core.setFailed.called, false);
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, false);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.strictEqual(mocks.core.setFailed.mock.callCount(), 0);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], false);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[0],
|
||||
"response",
|
||||
);
|
||||
response.body = response.data;
|
||||
response.data = undefined;
|
||||
assert.deepEqual(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify(response),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(2).firstArg, "time");
|
||||
assert.equal(mocks.core.setOutput.getCalls().length, 3);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[2].arguments[0], "time");
|
||||
assert.equal(mocks.core.setOutput.mock.calls.length, 3);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -367,26 +428,34 @@ describe("client", () => {
|
||||
error: "missing_channel",
|
||||
},
|
||||
};
|
||||
mocks.booleanInputs = {
|
||||
...mocks.booleanInputs,
|
||||
errors: true,
|
||||
};
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
token: "xoxb-example",
|
||||
payload: `"text": "hello"`,
|
||||
};
|
||||
mocks.calls._rejectsWith = errors.platformErrorFromResult(response);
|
||||
try {
|
||||
mocks.core.getInput.reset();
|
||||
mocks.core.getBooleanInput.withArgs("errors").returns(true);
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.core.getInput.withArgs("payload").returns(`"text": "hello"`);
|
||||
mocks.calls.rejects(errors.platformErrorFromResult(response));
|
||||
await send(mocks.core);
|
||||
assert.fail("Expected an error but none was found");
|
||||
} catch (_err) {
|
||||
assert.ok(mocks.core.setFailed.called);
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, false);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.ok(mocks.core.setFailed.mock.callCount() > 0);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], false);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[0],
|
||||
"response",
|
||||
);
|
||||
assert.deepEqual(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify(response),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(2).firstArg, "time");
|
||||
assert.equal(mocks.core.setOutput.getCalls().length, 3);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[2].arguments[0], "time");
|
||||
assert.equal(mocks.core.setOutput.mock.calls.length, 3);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -398,24 +467,30 @@ describe("client", () => {
|
||||
error: "missing_channel",
|
||||
},
|
||||
};
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
token: "xoxb-example",
|
||||
payload: `"text": "hello"`,
|
||||
};
|
||||
mocks.calls._rejectsWith = errors.platformErrorFromResult(response);
|
||||
try {
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.core.getInput.withArgs("payload").returns(`"text": "hello"`);
|
||||
mocks.calls.rejects(errors.platformErrorFromResult(response));
|
||||
await send(mocks.core);
|
||||
assert.fail("Expected an error but none was found");
|
||||
} catch (_err) {
|
||||
assert.strictEqual(mocks.core.setFailed.called, false);
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, false);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.strictEqual(mocks.core.setFailed.mock.callCount(), 0);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], false);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[0],
|
||||
"response",
|
||||
);
|
||||
assert.deepEqual(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify(response),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(2).firstArg, "time");
|
||||
assert.equal(mocks.core.setOutput.getCalls().length, 3);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[2].arguments[0], "time");
|
||||
assert.equal(mocks.core.setOutput.mock.calls.length, 3);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -424,24 +499,30 @@ describe("client", () => {
|
||||
code: "slack_webapi_rate_limited_error",
|
||||
retryAfter: 12,
|
||||
};
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
token: "xoxb-example",
|
||||
payload: `"text": "hello"`,
|
||||
};
|
||||
mocks.calls._rejectsWith = errors.rateLimitedErrorWithDelay(12);
|
||||
try {
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.core.getInput.withArgs("payload").returns(`"text": "hello"`);
|
||||
mocks.calls.rejects(errors.rateLimitedErrorWithDelay(12));
|
||||
await send(mocks.core);
|
||||
assert.fail("Expected an error but none was found");
|
||||
} catch (_err) {
|
||||
assert.strictEqual(mocks.core.setFailed.called, false);
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, false);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.strictEqual(mocks.core.setFailed.mock.callCount(), 0);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], false);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[0],
|
||||
"response",
|
||||
);
|
||||
assert.deepEqual(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify(response),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(2).firstArg, "time");
|
||||
assert.equal(mocks.core.setOutput.getCalls().length, 3);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[2].arguments[0], "time");
|
||||
assert.equal(mocks.core.setOutput.mock.calls.length, 3);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -449,9 +530,12 @@ describe("client", () => {
|
||||
describe("proxies", () => {
|
||||
it("sets up the proxy agent for the provided https proxy", async () => {
|
||||
const proxy = "https://example.com";
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("proxy").returns(proxy);
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
proxy,
|
||||
token: "xoxb-example",
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const client = new Client();
|
||||
const { httpsAgent, proxy: proxying } = client.proxies(config);
|
||||
@@ -461,9 +545,12 @@ describe("client", () => {
|
||||
|
||||
it("fails to configure proxies with an invalid proxied url", async () => {
|
||||
const proxy = "https://";
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("proxy").returns(proxy);
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
proxy,
|
||||
token: "xoxb-example",
|
||||
};
|
||||
try {
|
||||
const config = new Config(mocks.core);
|
||||
const client = new Client();
|
||||
|
||||
+107
-41
@@ -20,13 +20,19 @@ describe("config", () => {
|
||||
|
||||
describe("inputs", () => {
|
||||
it("valid values are collected from the action inputs", async () => {
|
||||
mocks.core.getInput.withArgs("api").returns("http://localhost:8080");
|
||||
mocks.core.getBooleanInput.withArgs("errors").returns(true);
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("payload").returns('"hello": "world"');
|
||||
mocks.core.getInput.withArgs("proxy").returns("https://example.com");
|
||||
mocks.core.getInput.withArgs("retries").returns("0");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
api: "http://localhost:8080",
|
||||
method: "chat.postMessage",
|
||||
payload: '"hello": "world"',
|
||||
proxy: "https://example.com",
|
||||
retries: "0",
|
||||
token: "xoxb-example",
|
||||
};
|
||||
mocks.booleanInputs = {
|
||||
...mocks.booleanInputs,
|
||||
errors: true,
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
assert.equal(config.inputs.api, "http://localhost:8080");
|
||||
assert.equal(config.inputs.errors, true);
|
||||
@@ -35,36 +41,65 @@ describe("config", () => {
|
||||
assert.equal(config.inputs.proxy, "https://example.com");
|
||||
assert.equal(config.inputs.retries, config.Retries.ZERO);
|
||||
assert.equal(config.inputs.token, "xoxb-example");
|
||||
assert.ok(mocks.core.setSecret.withArgs("xoxb-example").called);
|
||||
assert.ok(
|
||||
mocks.core.setSecret.mock.calls.some(
|
||||
(c) => c.arguments[0] === "xoxb-example",
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it("allows token environment variables with a webhook", async () => {
|
||||
process.env.SLACK_TOKEN = "xoxb-example";
|
||||
mocks.core.getInput.withArgs("webhook").returns("https://example.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://example.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
assert.equal(config.inputs.token, "xoxb-example");
|
||||
assert.equal(config.inputs.webhook, "https://example.com");
|
||||
assert.equal(config.inputs.webhookType, "incoming-webhook");
|
||||
assert.ok(mocks.core.setSecret.withArgs("xoxb-example").called);
|
||||
assert.ok(mocks.core.setSecret.withArgs("https://example.com").called);
|
||||
assert.ok(
|
||||
mocks.core.setSecret.mock.calls.some(
|
||||
(c) => c.arguments[0] === "xoxb-example",
|
||||
),
|
||||
);
|
||||
assert.ok(
|
||||
mocks.core.setSecret.mock.calls.some(
|
||||
(c) => c.arguments[0] === "https://example.com",
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it("allows webhook environment variables with a token", async () => {
|
||||
process.env.SLACK_WEBHOOK_URL = "https://example.com";
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
token: "xoxb-example",
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
assert.equal(config.inputs.method, "chat.postMessage");
|
||||
assert.equal(config.inputs.token, "xoxb-example");
|
||||
assert.equal(config.inputs.webhook, "https://example.com");
|
||||
assert.ok(mocks.core.setSecret.withArgs("xoxb-example").called);
|
||||
assert.ok(mocks.core.setSecret.withArgs("https://example.com").called);
|
||||
assert.ok(
|
||||
mocks.core.setSecret.mock.calls.some(
|
||||
(c) => c.arguments[0] === "xoxb-example",
|
||||
),
|
||||
);
|
||||
assert.ok(
|
||||
mocks.core.setSecret.mock.calls.some(
|
||||
(c) => c.arguments[0] === "https://example.com",
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it("errors when both the token and webhook is provided", async () => {
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.core.getInput.withArgs("webhook").returns("https://example.com");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
token: "xoxb-example",
|
||||
webhook: "https://example.com",
|
||||
};
|
||||
try {
|
||||
new Config(mocks.core);
|
||||
assert.fail("Failed to error when invalid inputs are provided");
|
||||
@@ -75,9 +110,15 @@ describe("config", () => {
|
||||
"Invalid input! Either the token or webhook is required - not both.",
|
||||
),
|
||||
);
|
||||
assert.ok(mocks.core.setSecret.withArgs("xoxb-example").called);
|
||||
assert.ok(
|
||||
mocks.core.setSecret.withArgs("https://example.com").called,
|
||||
mocks.core.setSecret.mock.calls.some(
|
||||
(c) => c.arguments[0] === "xoxb-example",
|
||||
),
|
||||
);
|
||||
assert.ok(
|
||||
mocks.core.setSecret.mock.calls.some(
|
||||
(c) => c.arguments[0] === "https://example.com",
|
||||
),
|
||||
);
|
||||
} else {
|
||||
assert.fail(err);
|
||||
@@ -86,7 +127,10 @@ describe("config", () => {
|
||||
});
|
||||
|
||||
it("errors if the method is provided without a token", async () => {
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
};
|
||||
try {
|
||||
new Config(mocks.core);
|
||||
assert.fail("Failed to error when invalid inputs are provided");
|
||||
@@ -121,7 +165,10 @@ describe("config", () => {
|
||||
});
|
||||
|
||||
it("errors if a webhook is provided without the type", async () => {
|
||||
mocks.core.getInput.withArgs("webhook").returns("https://example.com");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://example.com",
|
||||
};
|
||||
try {
|
||||
new Config(mocks.core);
|
||||
assert.fail("Failed to error when invalid inputs are provided");
|
||||
@@ -139,8 +186,11 @@ describe("config", () => {
|
||||
});
|
||||
|
||||
it("errors if the webhook type does not match techniques", async () => {
|
||||
mocks.core.getInput.withArgs("webhook").returns("https://example.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("post");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://example.com",
|
||||
"webhook-type": "post",
|
||||
};
|
||||
try {
|
||||
new Config(mocks.core);
|
||||
assert.fail("Failed to error when invalid inputs are provided");
|
||||
@@ -160,35 +210,50 @@ describe("config", () => {
|
||||
|
||||
describe("mask", async () => {
|
||||
it("treats the provided token as a secret", async () => {
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
token: "xoxb-example",
|
||||
};
|
||||
try {
|
||||
await send(mocks.core);
|
||||
assert.fail("Failed to error for incomplete inputs while testing");
|
||||
} catch {
|
||||
assert.ok(mocks.core.setSecret.withArgs("xoxb-example").called);
|
||||
assert.ok(
|
||||
mocks.core.setSecret.mock.calls.some(
|
||||
(c) => c.arguments[0] === "xoxb-example",
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("treats the provided webhook as a secret", async () => {
|
||||
mocks.core.getInput.withArgs("webhook").returns("https://slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://slack.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
};
|
||||
try {
|
||||
await send(mocks.core);
|
||||
assert.fail("Failed to error for incomplete inputs while testing");
|
||||
} catch {
|
||||
assert.ok(mocks.core.setSecret.withArgs("https://slack.com").called);
|
||||
assert.ok(
|
||||
mocks.core.setSecret.mock.calls.some(
|
||||
(c) => c.arguments[0] === "https://slack.com",
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("validate", () => {
|
||||
it('allow the "retries" option with lowercased space', async () => {
|
||||
mocks.axios.post.returns(Promise.resolve("LGTM"));
|
||||
mocks.core.getInput.withArgs("retries").returns(" rapid ");
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.axios.post._promise = Promise.resolve("LGTM");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
retries: " rapid ",
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
};
|
||||
try {
|
||||
await send(mocks.core);
|
||||
} catch (err) {
|
||||
@@ -205,12 +270,13 @@ describe("config", () => {
|
||||
});
|
||||
|
||||
it("errors if an invalid retries option is provided", async () => {
|
||||
mocks.axios.post.returns(Promise.resolve("LGTM"));
|
||||
mocks.core.getInput.withArgs("retries").returns("FOREVER");
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.axios.post._promise = Promise.resolve("LGTM");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
retries: "FOREVER",
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
};
|
||||
try {
|
||||
await send(mocks.core);
|
||||
} catch (err) {
|
||||
|
||||
+118
-134
@@ -1,6 +1,7 @@
|
||||
import assert from "node:assert";
|
||||
import path from "node:path";
|
||||
import { dirname, join } from "node:path";
|
||||
import { beforeEach, describe, it } from "node:test";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { YAMLException } from "js-yaml";
|
||||
import Config from "../src/config.js";
|
||||
import Content from "../src/content.js";
|
||||
@@ -8,25 +9,36 @@ import SlackError from "../src/errors.js";
|
||||
import send from "../src/send.js";
|
||||
import { mocks } from "./index.spec.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const FIXTURES = join(__dirname, "fixtures");
|
||||
|
||||
/**
|
||||
* Confirm values from the action input or environment variables are gathered
|
||||
*/
|
||||
describe("content", () => {
|
||||
beforeEach(() => {
|
||||
mocks.reset();
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
token: "xoxb-example",
|
||||
};
|
||||
// Set up default apiCall mock for tests that use send()
|
||||
mocks.calls._resolvesWith = { ok: true };
|
||||
});
|
||||
|
||||
describe("flatten", () => {
|
||||
it("flattens nested payloads provided with delimiter", async () => {
|
||||
mocks.core.getInput.withArgs("payload").returns(`
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
payload: `
|
||||
"apples": "tree",
|
||||
"bananas": {
|
||||
"truthiness": true
|
||||
}
|
||||
`);
|
||||
mocks.core.getInput.withArgs("payload-delimiter").returns("_");
|
||||
`,
|
||||
"payload-delimiter": "_",
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
apples: "tree",
|
||||
@@ -38,8 +50,11 @@ describe("content", () => {
|
||||
|
||||
describe("get", () => {
|
||||
it("errors if both a payload and file path are provided", async () => {
|
||||
mocks.core.getInput.withArgs("payload").returns(`"message"="hello"`);
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("example.json");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
payload: `"message"="hello"`,
|
||||
"payload-file-path": "example.json",
|
||||
};
|
||||
try {
|
||||
await send(mocks.core);
|
||||
assert.fail("Failed to throw for invalid input");
|
||||
@@ -59,10 +74,13 @@ describe("content", () => {
|
||||
|
||||
describe("payload", async () => {
|
||||
it("parses complete YAML from the input payload", async () => {
|
||||
mocks.core.getInput.withArgs("payload").returns(`
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
payload: `
|
||||
message: "this is wrapped"
|
||||
channel: "C0123456789"
|
||||
`);
|
||||
`,
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
message: "this is wrapped",
|
||||
@@ -72,11 +90,14 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("parses complete JSON from the input payload", async () => {
|
||||
mocks.core.getInput.withArgs("payload").returns(`{
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
payload: `{
|
||||
"message": "this is wrapped",
|
||||
"channel": "C0123456789"
|
||||
}
|
||||
`);
|
||||
`,
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
message: "this is wrapped",
|
||||
@@ -86,11 +107,14 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("templatizes variables requires configuration", async () => {
|
||||
mocks.core.getInput.withArgs("payload").returns(`{
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
payload: `{
|
||||
"message": "this matches an existing variable: \${{ github.apiUrl }}",
|
||||
"channel": "C0123456789"
|
||||
}
|
||||
`);
|
||||
`,
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
// biome-ignore-start lint/suspicious/noTemplateCurlyInString: GitHub Action YAML variable syntax
|
||||
const expected = {
|
||||
@@ -102,7 +126,9 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("templatizes variables with matching variables", async () => {
|
||||
mocks.core.getInput.withArgs("payload").returns(`
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
payload: `
|
||||
channel: C0123456789
|
||||
reply_broadcast: false
|
||||
message: Served \${{ env.NUMBER }} items
|
||||
@@ -136,8 +162,12 @@ describe("content", () => {
|
||||
type: plain_text
|
||||
text: "\${{ github.graphqlUrl }}"
|
||||
value: graphql
|
||||
`);
|
||||
mocks.core.getBooleanInput.withArgs("payload-templated").returns(true);
|
||||
`,
|
||||
};
|
||||
mocks.booleanInputs = {
|
||||
...mocks.booleanInputs,
|
||||
"payload-templated": true,
|
||||
};
|
||||
process.env.DETAILS = `
|
||||
-fri
|
||||
-sat
|
||||
@@ -210,11 +240,15 @@ describe("content", () => {
|
||||
*/
|
||||
it("templatizes variables with missing variables", async () => {
|
||||
// biome-ignore-start lint/suspicious/noTemplateCurlyInString: GitHub Action YAML variable syntax
|
||||
mocks.core.getInput
|
||||
.withArgs("payload")
|
||||
.returns("message: What makes ${{ env.TREASURE }} a secret");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
payload: "message: What makes ${{ env.TREASURE }} a secret",
|
||||
};
|
||||
// biome-ignore-end lint/suspicious/noTemplateCurlyInString: https://docs.github.com/en/actions/how-tos/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#using-contexts-to-access-variable-values
|
||||
mocks.core.getBooleanInput.withArgs("payload-templated").returns(true);
|
||||
mocks.booleanInputs = {
|
||||
...mocks.booleanInputs,
|
||||
"payload-templated": true,
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
message: "What makes ??? a secret",
|
||||
@@ -223,10 +257,13 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("trims last comma JSON with the input payload", async () => {
|
||||
mocks.core.getInput.withArgs("payload").returns(`
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
payload: `
|
||||
"message": "LGTM!",
|
||||
"channel": "C0123456789",
|
||||
`);
|
||||
`,
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
message: "LGTM!",
|
||||
@@ -236,7 +273,9 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("wraps incomplete JSON from the input payload", async () => {
|
||||
mocks.core.getInput.withArgs("payload").returns(`
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
payload: `
|
||||
"message": "LGTM!",
|
||||
"channel": "C0123456789",
|
||||
"blocks": [
|
||||
@@ -247,7 +286,8 @@ describe("content", () => {
|
||||
}
|
||||
}
|
||||
]
|
||||
`);
|
||||
`,
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
message: "LGTM!",
|
||||
@@ -291,7 +331,10 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("fails if invalid JSON exists in the input payload", async () => {
|
||||
mocks.core.getInput.withArgs("payload").returns("{");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
payload: "{",
|
||||
};
|
||||
try {
|
||||
await send(mocks.core);
|
||||
assert.fail("Failed to throw for invalid JSON");
|
||||
@@ -316,13 +359,10 @@ describe("content", () => {
|
||||
|
||||
describe("payload file", async () => {
|
||||
it("parses complete YAML from the input payload file", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("example.yaml");
|
||||
mocks.fs.readFileSync
|
||||
.withArgs(path.resolve("example.yaml"), "utf-8")
|
||||
.returns(`
|
||||
message: "drink water"
|
||||
channel: "C6H12O6H2O2"
|
||||
`);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
"payload-file-path": join(FIXTURES, "payload.yaml"),
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
message: "drink water",
|
||||
@@ -332,13 +372,10 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("parses complete YML from the input payload file", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("example.yml");
|
||||
mocks.fs.readFileSync
|
||||
.withArgs(path.resolve("example.yml"), "utf-8")
|
||||
.returns(`
|
||||
message: "drink coffee"
|
||||
channel: "C0FFEEEEEEEE"
|
||||
`);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
"payload-file-path": join(FIXTURES, "payload.yml"),
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
message: "drink coffee",
|
||||
@@ -348,13 +385,10 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("parses complete JSON from the input payload file", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("example.json");
|
||||
mocks.fs.readFileSync
|
||||
.withArgs(path.resolve("example.json"), "utf-8")
|
||||
.returns(`{
|
||||
"message": "drink water",
|
||||
"channel": "C6H12O6H2O2"
|
||||
}`);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
"payload-file-path": join(FIXTURES, "payload.json"),
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
message: "drink water",
|
||||
@@ -364,14 +398,10 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("templatizes variables requires configuration", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("example.json");
|
||||
mocks.fs.readFileSync
|
||||
.withArgs(path.resolve("example.json"), "utf-8")
|
||||
.returns(`{
|
||||
"message": "this matches an existing variable: \${{ github.apiUrl }}",
|
||||
"channel": "C0123456789"
|
||||
}
|
||||
`);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
"payload-file-path": join(FIXTURES, "payload-with-github-vars.json"),
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
// biome-ignore-start lint/suspicious/noTemplateCurlyInString: GitHub Action YAML variable syntax
|
||||
const expected = {
|
||||
@@ -383,66 +413,14 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("templatizes variables with matching variables", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("example.json");
|
||||
mocks.fs.readFileSync
|
||||
.withArgs(path.resolve("example.json"), "utf-8")
|
||||
.returns(`{
|
||||
"channel": "C0123456789",
|
||||
"reply_broadcast": false,
|
||||
"message": "Served \${{ env.NUMBER }} items",
|
||||
"blocks": [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "Served \${{ env.NUMBER }} items on: \${{ env.DETAILS }}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "divider"
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"block_id": "selector",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "Send feedback"
|
||||
},
|
||||
"accessory": {
|
||||
"action_id": "response",
|
||||
"type": "multi_static_select",
|
||||
"placeholder": {
|
||||
"type": "plain_text",
|
||||
"text": "Select URL"
|
||||
},
|
||||
"options": [
|
||||
{
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "\${{ github.apiUrl }}"
|
||||
},
|
||||
"value": "api"
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "\${{ github.serverUrl }}"
|
||||
},
|
||||
"value": "server"
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "\${{ github.graphqlUrl }}"
|
||||
},
|
||||
"value": "graphql"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}`);
|
||||
mocks.core.getBooleanInput.withArgs("payload-templated").returns(true);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
"payload-file-path": join(FIXTURES, "payload-with-env-vars.json"),
|
||||
};
|
||||
mocks.booleanInputs = {
|
||||
...mocks.booleanInputs,
|
||||
"payload-templated": true,
|
||||
};
|
||||
process.env.DETAILS = `
|
||||
-fri
|
||||
-sat
|
||||
@@ -514,13 +492,14 @@ describe("content", () => {
|
||||
* @see {@link https://github.com/slackapi/slack-github-action/issues/203}
|
||||
*/
|
||||
it("templatizes variables with missing variables", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("example.json");
|
||||
mocks.fs.readFileSync
|
||||
.withArgs(path.resolve("example.json"), "utf-8")
|
||||
.returns(`{
|
||||
"message": "What makes $\{{ env.TREASURE }} a secret"
|
||||
}`);
|
||||
mocks.core.getBooleanInput.withArgs("payload-templated").returns(true);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
"payload-file-path": join(FIXTURES, "payload-with-missing-var.json"),
|
||||
};
|
||||
mocks.booleanInputs = {
|
||||
...mocks.booleanInputs,
|
||||
"payload-templated": true,
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
message: "What makes ??? a secret",
|
||||
@@ -553,7 +532,10 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("fails to parse a file path that does not exist", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("unknown.json");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
"payload-file-path": join(FIXTURES, "nonexistent.json"),
|
||||
};
|
||||
try {
|
||||
await send(mocks.core);
|
||||
assert.fail("Failed to throw for nonexistent files");
|
||||
@@ -571,7 +553,10 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("fails to parse a file with an unknown extension", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("unknown.md");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
"payload-file-path": join(FIXTURES, "payload.yaml.md"),
|
||||
};
|
||||
try {
|
||||
await send(mocks.core);
|
||||
assert.fail("Failed to throw for an unknown extension");
|
||||
@@ -586,7 +571,7 @@ describe("content", () => {
|
||||
assert.equal(err.cause.values.length, 1);
|
||||
assert.ok(
|
||||
err.cause.values[0].message.includes(
|
||||
"Invalid input! Failed to parse file extension unknown.md",
|
||||
"Invalid input! Failed to parse file extension",
|
||||
),
|
||||
);
|
||||
} else {
|
||||
@@ -596,11 +581,10 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("fails if invalid JSON exists in the input payload", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("example.json");
|
||||
mocks.fs.readFileSync
|
||||
.withArgs(path.resolve("example.json"), "utf-8")
|
||||
.returns(`{
|
||||
"message": "a truncated file without an end`);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
"payload-file-path": join(FIXTURES, "payload-invalid.json"),
|
||||
};
|
||||
try {
|
||||
await send(mocks.core);
|
||||
assert.fail("Failed to throw for invalid JSON");
|
||||
@@ -621,10 +605,10 @@ describe("content", () => {
|
||||
});
|
||||
|
||||
it("fails if invalid YAML exists in the input payload", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("example.yaml");
|
||||
mocks.fs.readFileSync
|
||||
.withArgs(path.resolve("example.yaml"), "utf-8")
|
||||
.returns(`- "message": "assigned": "values"`);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
"payload-file-path": join(FIXTURES, "payload-invalid.yaml"),
|
||||
};
|
||||
try {
|
||||
await send(mocks.core);
|
||||
assert.fail("Failed to throw for invalid YAML");
|
||||
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
{
|
||||
"message": "a truncated file without an end
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
- "message": "assigned": "values"
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"channel": "C0123456789",
|
||||
"reply_broadcast": false,
|
||||
"message": "Served ${{ env.NUMBER }} items",
|
||||
"blocks": [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "Served ${{ env.NUMBER }} items on: ${{ env.DETAILS }}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "divider"
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"block_id": "selector",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "Send feedback"
|
||||
},
|
||||
"accessory": {
|
||||
"action_id": "response",
|
||||
"type": "multi_static_select",
|
||||
"placeholder": {
|
||||
"type": "plain_text",
|
||||
"text": "Select URL"
|
||||
},
|
||||
"options": [
|
||||
{
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "${{ github.apiUrl }}"
|
||||
},
|
||||
"value": "api"
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "${{ github.serverUrl }}"
|
||||
},
|
||||
"value": "server"
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "${{ github.graphqlUrl }}"
|
||||
},
|
||||
"value": "graphql"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"message": "this matches an existing variable: ${{ github.apiUrl }}",
|
||||
"channel": "C0123456789"
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"message": "What makes ${{ env.TREASURE }} a secret"
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"message": "drink water",
|
||||
"channel": "C6H12O6H2O2"
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
message: "drink water"
|
||||
channel: "C6H12O6H2O2"
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
# This file has an unknown extension
|
||||
message: "test"
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
message: "drink coffee"
|
||||
channel: "C0FFEEEEEEEE"
|
||||
+67
-49
@@ -1,7 +1,6 @@
|
||||
import fs from "node:fs";
|
||||
import { mock } from "node:test";
|
||||
import webapi from "@slack/web-api";
|
||||
import axios, { AxiosError } from "axios";
|
||||
import sinon from "sinon";
|
||||
|
||||
/**
|
||||
* Hello experimenter! These tests are here to confirm that the happy paths keep
|
||||
@@ -35,65 +34,84 @@ export class Mock {
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup stubbed dependencies and configure default input arguments for all
|
||||
* Lookup tables for input values.
|
||||
*/
|
||||
inputs = {};
|
||||
booleanInputs = {};
|
||||
|
||||
/**
|
||||
* Setup mocked dependencies and configure default input arguments for all
|
||||
* tests.
|
||||
*
|
||||
* @see {@link ../action.yml}
|
||||
*/
|
||||
constructor() {
|
||||
this.sandbox = sinon.createSandbox();
|
||||
this.axios = this.sandbox.stub(axios);
|
||||
this.calls = this.sandbox.stub(webapi.WebClient.prototype, "apiCall");
|
||||
this.axios = {
|
||||
post: mock.fn((..._args) => {
|
||||
if (this.axios.post._promise !== undefined) {
|
||||
return this.axios.post._promise;
|
||||
}
|
||||
throw new Error(
|
||||
"Test error: axios.post was called but no promise was configured. " +
|
||||
"Set mocks.axios.post._promise = Promise.resolve(...) or Promise.reject(...)",
|
||||
);
|
||||
}),
|
||||
};
|
||||
axios.post = this.axios.post;
|
||||
this.calls = mock.fn((..._args) => {
|
||||
if (this.calls._resolvesWith !== undefined) {
|
||||
return Promise.resolve(this.calls._resolvesWith);
|
||||
}
|
||||
if (this.calls._rejectsWith !== undefined) {
|
||||
return Promise.reject(this.calls._rejectsWith);
|
||||
}
|
||||
throw new Error(
|
||||
"Test error: apiCall was called but no promise was configured. " +
|
||||
"Set mocks.calls._resolvesWith = {...} or mocks.calls._rejectsWith = {...}",
|
||||
);
|
||||
});
|
||||
webapi.WebClient.prototype.apiCall = this.calls;
|
||||
this.core = {
|
||||
debug: this.sandbox.stub(),
|
||||
error: this.sandbox.stub(),
|
||||
getInput: this.sandbox.stub(),
|
||||
getBooleanInput: this.sandbox.stub(),
|
||||
info: this.sandbox.stub(),
|
||||
isDebug: this.sandbox.stub(),
|
||||
setFailed: this.sandbox.stub(),
|
||||
setOutput: this.sandbox.stub(),
|
||||
setSecret: this.sandbox.stub(),
|
||||
warning: this.sandbox.stub(),
|
||||
debug: mock.fn(),
|
||||
error: mock.fn(),
|
||||
getInput: mock.fn((key) => this.inputs[key] ?? ""),
|
||||
getBooleanInput: mock.fn((key) => this.booleanInputs[key] ?? false),
|
||||
info: mock.fn(),
|
||||
isDebug: mock.fn(() => this._isDebug ?? false),
|
||||
setFailed: mock.fn(),
|
||||
setOutput: mock.fn(),
|
||||
setSecret: mock.fn(),
|
||||
warning: mock.fn(),
|
||||
};
|
||||
this.fs = this.sandbox.stub(fs);
|
||||
this.webapi = {
|
||||
WebClient: function () {
|
||||
this.apiCall = () => ({
|
||||
ok: true,
|
||||
});
|
||||
},
|
||||
};
|
||||
this.core.getInput.withArgs("errors").returns("false");
|
||||
this.core.getInput.withArgs("retries").returns("5");
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing interface that removes internal state from existing stubs.
|
||||
* Testing interface that removes internal state from existing mocks.
|
||||
*/
|
||||
reset() {
|
||||
this.sandbox.reset();
|
||||
this.axios.post.resetHistory();
|
||||
this.calls.resetHistory();
|
||||
this.core.debug.reset();
|
||||
this.core.error.reset();
|
||||
this.core.getInput.reset();
|
||||
this.core.getBooleanInput.reset();
|
||||
this.core.info.reset();
|
||||
this.core.isDebug.reset();
|
||||
this.core.setFailed.reset();
|
||||
this.core.setOutput.reset();
|
||||
this.core.setSecret.reset();
|
||||
this.core.warning.reset();
|
||||
this.webapi = {
|
||||
WebClient: function () {
|
||||
this.apiCall = () => ({
|
||||
ok: true,
|
||||
});
|
||||
},
|
||||
};
|
||||
this.core.getInput.withArgs("errors").returns("false");
|
||||
this.core.getInput.withArgs("retries").returns("5");
|
||||
// Clear lookup tables
|
||||
this.inputs = {};
|
||||
this.booleanInputs = {};
|
||||
|
||||
// Reset axios mock
|
||||
this.axios.post.mock.resetCalls();
|
||||
this.axios.post._promise = undefined;
|
||||
|
||||
// Reset apiCall mock
|
||||
this.calls.mock.resetCalls();
|
||||
this.calls._resolvesWith = undefined;
|
||||
this.calls._rejectsWith = undefined;
|
||||
|
||||
// Reset core mocks
|
||||
for (const fn of Object.values(this.core)) {
|
||||
fn.mock?.resetCalls();
|
||||
}
|
||||
this._isDebug = false;
|
||||
|
||||
// Reset webapi
|
||||
this.webapi = {};
|
||||
|
||||
// Clear environment variables
|
||||
process.env.SLACK_TOKEN = "";
|
||||
process.env.SLACK_WEBHOOK_URL = "";
|
||||
}
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ describe("logger", () => {
|
||||
|
||||
describe("level", () => {
|
||||
it("debug", () => {
|
||||
mocks.core.isDebug.returns(true);
|
||||
mocks._isDebug = true;
|
||||
const { logger } = new Logger(mocks.core);
|
||||
const actual = logger.getLevel();
|
||||
const expected = LogLevel.DEBUG;
|
||||
@@ -19,7 +19,7 @@ describe("logger", () => {
|
||||
});
|
||||
|
||||
it("info", () => {
|
||||
mocks.core.isDebug.returns(false);
|
||||
mocks._isDebug = false;
|
||||
const { logger } = new Logger(mocks.core);
|
||||
const actual = logger.getLevel();
|
||||
const expected = LogLevel.INFO;
|
||||
|
||||
+42
-36
@@ -19,62 +19,68 @@ describe("send", () => {
|
||||
|
||||
describe("techniques", async () => {
|
||||
it("webhook trigger", async () => {
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("webhook-trigger");
|
||||
mocks.core.getInput.withArgs("payload").returns('"greetings": "hello"');
|
||||
mocks.axios.post.returns(
|
||||
Promise.resolve({ status: 200, data: { ok: true } }),
|
||||
);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "webhook-trigger",
|
||||
payload: '"greetings": "hello"',
|
||||
};
|
||||
mocks.axios.post._promise = Promise.resolve({
|
||||
status: 200,
|
||||
data: { ok: true },
|
||||
});
|
||||
await send(mocks.core);
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, true);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], true);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[1].arguments[0], "response");
|
||||
assert.equal(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify({ ok: true }),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(2).firstArg, "time");
|
||||
assert.ok(mocks.core.setOutput.getCall(2).lastArg >= 0);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[2].arguments[0], "time");
|
||||
assert.ok(mocks.core.setOutput.mock.calls[2].arguments[1] >= 0);
|
||||
});
|
||||
|
||||
it("token", async () => {
|
||||
process.env.SLACK_WEBHOOK_URL = "https://example.com"; // https://github.com/slackapi/slack-github-action/issues/373
|
||||
mocks.calls.resolves({ ok: true });
|
||||
mocks.core.getInput.withArgs("method").returns("chat.postMessage");
|
||||
mocks.core.getInput.withArgs("token").returns("xoxb-example");
|
||||
mocks.core.getInput.withArgs("payload").returns('"text": "hello"');
|
||||
mocks.calls._resolvesWith = { ok: true };
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
method: "chat.postMessage",
|
||||
token: "xoxb-example",
|
||||
payload: '"text": "hello"',
|
||||
};
|
||||
await send(mocks.core);
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, true);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], true);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[1].arguments[0], "response");
|
||||
assert.equal(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify({ ok: true }),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(2).firstArg, "time");
|
||||
assert.ok(mocks.core.setOutput.getCall(2).lastArg >= 0);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[2].arguments[0], "time");
|
||||
assert.ok(mocks.core.setOutput.mock.calls[2].arguments[1] >= 0);
|
||||
});
|
||||
|
||||
it("incoming webhook", async () => {
|
||||
process.env.SLACK_TOKEN = "xoxb-example"; // https://github.com/slackapi/slack-github-action/issues/373
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.core.getInput.withArgs("payload").returns('"text": "hello"');
|
||||
mocks.axios.post.returns(Promise.resolve({ status: 200, data: "ok" }));
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
payload: '"text": "hello"',
|
||||
};
|
||||
mocks.axios.post._promise = Promise.resolve({ status: 200, data: "ok" });
|
||||
await send(mocks.core);
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, true);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], true);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[1].arguments[0], "response");
|
||||
assert.equal(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify("ok"),
|
||||
);
|
||||
assert.equal(mocks.core.setOutput.getCall(2).firstArg, "time");
|
||||
assert.ok(mocks.core.setOutput.getCall(2).lastArg >= 0);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[2].arguments[0], "time");
|
||||
assert.ok(mocks.core.setOutput.mock.calls[2].arguments[1] >= 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+91
-71
@@ -14,26 +14,32 @@ describe("webhook", () => {
|
||||
|
||||
describe("success", () => {
|
||||
it("sends the parsed payload to the provided webhook trigger", async () => {
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("webhook-trigger");
|
||||
mocks.core.getInput.withArgs("payload").returns("drinks: coffee");
|
||||
mocks.axios.post.returns(
|
||||
Promise.resolve({ status: 200, data: { ok: true } }),
|
||||
);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "webhook-trigger",
|
||||
payload: "drinks: coffee",
|
||||
};
|
||||
mocks.axios.post._promise = Promise.resolve({
|
||||
status: 200,
|
||||
data: { ok: true },
|
||||
});
|
||||
try {
|
||||
await send(mocks.core);
|
||||
assert.equal(mocks.axios.post.getCalls().length, 1);
|
||||
const [url, payload, options] = mocks.axios.post.getCall(0).args;
|
||||
assert.equal(mocks.axios.post.mock.calls.length, 1);
|
||||
const [url, payload, options] =
|
||||
mocks.axios.post.mock.calls[0].arguments;
|
||||
assert.equal(url, "https://hooks.slack.com");
|
||||
assert.deepEqual(payload, { drinks: "coffee" });
|
||||
assert.deepEqual(options, {});
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, true);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], true);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
mocks.core.setOutput.mock.calls[1].arguments[0],
|
||||
"response",
|
||||
);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify({ ok: true }),
|
||||
);
|
||||
} catch (err) {
|
||||
@@ -43,24 +49,29 @@ describe("webhook", () => {
|
||||
});
|
||||
|
||||
it("sends the parsed payload to the provided incoming webhook", async () => {
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.core.getInput.withArgs("payload").returns("text: greetings");
|
||||
mocks.axios.post.returns(Promise.resolve({ status: 200, data: "ok" }));
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
payload: "text: greetings",
|
||||
};
|
||||
mocks.axios.post._promise = Promise.resolve({ status: 200, data: "ok" });
|
||||
try {
|
||||
await send(mocks.core);
|
||||
assert.equal(mocks.axios.post.getCalls().length, 1);
|
||||
const [url, payload, options] = mocks.axios.post.getCall(0).args;
|
||||
assert.equal(mocks.axios.post.mock.calls.length, 1);
|
||||
const [url, payload, options] =
|
||||
mocks.axios.post.mock.calls[0].arguments;
|
||||
assert.equal(url, "https://hooks.slack.com");
|
||||
assert.deepEqual(payload, { text: "greetings" });
|
||||
assert.deepEqual(options, {});
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, true);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], true);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.getCall(1).lastArg,
|
||||
mocks.core.setOutput.mock.calls[1].arguments[0],
|
||||
"response",
|
||||
);
|
||||
assert.equal(
|
||||
mocks.core.setOutput.mock.calls[1].arguments[1],
|
||||
JSON.stringify("ok"),
|
||||
);
|
||||
} catch (err) {
|
||||
@@ -92,11 +103,12 @@ describe("webhook", () => {
|
||||
});
|
||||
|
||||
it("returns the failures from a webhook trigger", async () => {
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("webhook-trigger");
|
||||
mocks.core.getInput.withArgs("payload").returns("drinks: coffee");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "webhook-trigger",
|
||||
payload: "drinks: coffee",
|
||||
};
|
||||
const response = new AxiosError(
|
||||
"Request failed with status code 400",
|
||||
"ERR_BAD_REQUEST",
|
||||
@@ -104,7 +116,7 @@ describe("webhook", () => {
|
||||
{},
|
||||
{ status: 400 },
|
||||
);
|
||||
mocks.axios.post.resolves(Promise.reject(response));
|
||||
mocks.axios.post._promise = Promise.reject(response);
|
||||
try {
|
||||
await send(mocks.core);
|
||||
} catch (err) {
|
||||
@@ -116,22 +128,23 @@ describe("webhook", () => {
|
||||
assert.fail(err);
|
||||
}
|
||||
}
|
||||
assert.equal(mocks.axios.post.getCalls().length, 1);
|
||||
const [url, payload, options] = mocks.axios.post.getCall(0).args;
|
||||
assert.equal(mocks.axios.post.mock.calls.length, 1);
|
||||
const [url, payload, options] = mocks.axios.post.mock.calls[0].arguments;
|
||||
assert.equal(url, "https://hooks.slack.com");
|
||||
assert.deepEqual(payload, { drinks: "coffee" });
|
||||
assert.deepEqual(options, {});
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, false);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], false);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[1].arguments[0], "response");
|
||||
});
|
||||
|
||||
it("returns the failures from an incoming webhook", async () => {
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.core.getInput.withArgs("payload").returns("textt: oops");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
payload: "textt: oops",
|
||||
};
|
||||
const response = new AxiosError(
|
||||
"Request failed with status code 400",
|
||||
"ERR_BAD_REQUEST",
|
||||
@@ -139,7 +152,7 @@ describe("webhook", () => {
|
||||
{},
|
||||
{ status: 400 },
|
||||
);
|
||||
mocks.axios.post.resolves(Promise.reject(response));
|
||||
mocks.axios.post._promise = Promise.reject(response);
|
||||
try {
|
||||
await send(mocks.core);
|
||||
} catch (err) {
|
||||
@@ -151,14 +164,14 @@ describe("webhook", () => {
|
||||
assert.fail(err);
|
||||
}
|
||||
}
|
||||
assert.equal(mocks.axios.post.getCalls().length, 1);
|
||||
const [url, payload, options] = mocks.axios.post.getCall(0).args;
|
||||
assert.equal(mocks.axios.post.mock.calls.length, 1);
|
||||
const [url, payload, options] = mocks.axios.post.mock.calls[0].arguments;
|
||||
assert.equal(url, "https://hooks.slack.com");
|
||||
assert.deepEqual(payload, { textt: "oops" });
|
||||
assert.deepEqual(options, {});
|
||||
assert.equal(mocks.core.setOutput.getCall(0).firstArg, "ok");
|
||||
assert.equal(mocks.core.setOutput.getCall(0).lastArg, false);
|
||||
assert.equal(mocks.core.setOutput.getCall(1).firstArg, "response");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[0], "ok");
|
||||
assert.equal(mocks.core.setOutput.mock.calls[0].arguments[1], false);
|
||||
assert.equal(mocks.core.setOutput.mock.calls[1].arguments[0], "response");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -186,9 +199,12 @@ describe("webhook", () => {
|
||||
});
|
||||
|
||||
it("skips proxying an http webhook url altogether", async () => {
|
||||
mocks.core.getInput.withArgs("webhook").returns("http://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.core.getInput.withArgs("proxy").returns("https://example.com");
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "http://hooks.slack.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
proxy: "https://example.com",
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const webhook = new Webhook();
|
||||
const request = webhook.proxies(config);
|
||||
@@ -197,11 +213,12 @@ describe("webhook", () => {
|
||||
|
||||
it("sets up the proxy agent for the provided https proxy", async () => {
|
||||
const proxy = "https://example.com";
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.core.getInput.withArgs("proxy").returns(proxy);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
proxy,
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const webhook = new Webhook();
|
||||
const { httpsAgent, proxy: proxying } = webhook.proxies(config);
|
||||
@@ -211,11 +228,12 @@ describe("webhook", () => {
|
||||
|
||||
it("sets up the agent without proxy for http proxies", async () => {
|
||||
const proxy = "http://example.com";
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.core.getInput.withArgs("proxy").returns(proxy);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
proxy,
|
||||
};
|
||||
const config = new Config(mocks.core);
|
||||
const webhook = new Webhook();
|
||||
const { httpsAgent, proxy: proxying } = webhook.proxies(config);
|
||||
@@ -225,11 +243,12 @@ describe("webhook", () => {
|
||||
|
||||
it("fails to configure proxies with an invalid proxied url", async () => {
|
||||
const proxy = "https://";
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.core.getInput.withArgs("proxy").returns(proxy);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
proxy,
|
||||
};
|
||||
try {
|
||||
const config = new Config(mocks.core);
|
||||
const webhook = new Webhook();
|
||||
@@ -248,11 +267,12 @@ describe("webhook", () => {
|
||||
|
||||
it("fails to configure proxies with an unknown url protocol", async () => {
|
||||
const proxy = "ssh://";
|
||||
mocks.core.getInput
|
||||
.withArgs("webhook")
|
||||
.returns("https://hooks.slack.com");
|
||||
mocks.core.getInput.withArgs("webhook-type").returns("incoming-webhook");
|
||||
mocks.core.getInput.withArgs("proxy").returns(proxy);
|
||||
mocks.inputs = {
|
||||
...mocks.inputs,
|
||||
webhook: "https://hooks.slack.com",
|
||||
"webhook-type": "incoming-webhook",
|
||||
proxy,
|
||||
};
|
||||
try {
|
||||
const config = new Config(mocks.core);
|
||||
const webhook = new Webhook();
|
||||
|
||||
Reference in New Issue
Block a user