diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8ac6b8c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/.github/workflows/deno.yml b/.github/workflows/deno.yml index 1b288e3..a0a3966 100644 --- a/.github/workflows/deno.yml +++ b/.github/workflows/deno.yml @@ -2,9 +2,11 @@ name: Deno app build and testing on: push: - branches: [ main ] + branches: + - main pull_request: - branches: [ main ] + branches: + - main jobs: deno: @@ -18,7 +20,7 @@ jobs: - name: Setup Deno uses: denoland/setup-deno@v1 with: - deno-version: v1.x + deno-version: v2.x - name: Verify formatting run: deno fmt --check diff --git a/.gitignore b/.gitignore index 68dfaa9..1ca605b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ dist package .DS_Store -.slack/apps.dev.json diff --git a/.slack/.gitignore b/.slack/.gitignore new file mode 100644 index 0000000..973ba60 --- /dev/null +++ b/.slack/.gitignore @@ -0,0 +1,2 @@ +apps.dev.json +cache/ diff --git a/.slack/apps.json b/.slack/apps.json deleted file mode 100644 index 0967ef4..0000000 --- a/.slack/apps.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/slack.json b/.slack/hooks.json similarity index 100% rename from slack.json rename to .slack/hooks.json diff --git a/README.md b/README.md index 6f3af7d..1bd2718 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,10 @@ $ slack activity --tail Contains `apps.dev.json` and `apps.json`, which include installation details for development and deployed apps. +Contains `hooks.json` used by the CLI to interact with the project's SDK +dependencies. It contains script hooks that are executed by the CLI and +implemented by the SDK. + ### `datastores/` [Datastores](https://api.slack.com/automation/datastores) securely store data @@ -189,11 +193,6 @@ continuing to the next step. The [app manifest](https://api.slack.com/automation/manifest) contains the app's configuration. This file defines attributes like app name and description. -### `slack.json` - -Used by the CLI to interact with the project's SDK dependencies. It contains -script hooks that are executed by the CLI and implemented by the SDK. - ## Resources To learn more about developing automations on Slack, visit the following: diff --git a/deno.jsonc b/deno.jsonc index 56029c4..535414b 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,5 +1,5 @@ { - "$schema": "https://deno.land/x/deno/cli/schemas/config-file.v1.json", + "$schema": "https://raw.githubusercontent.com/denoland/deno/main/cli/schemas/config-file.v1.json", "fmt": { "include": [ "README.md", @@ -13,7 +13,6 @@ "workflows" ] }, - "importMap": "import_map.json", "lint": { "include": [ "datastores", @@ -28,6 +27,12 @@ }, "lock": false, "tasks": { - "test": "deno fmt --check && deno lint && deno test --allow-read --allow-none" + "test": "deno fmt --check && deno lint && deno test --allow-read" + }, + "imports": { + "@std/assert": "jsr:@std/assert@^1.0.13", + "@std/testing": "jsr:@std/testing@^1.0.12", + "deno-slack-sdk/": "https://deno.land/x/deno_slack_sdk@2.15.0/", + "deno-slack-api/": "https://deno.land/x/deno_slack_api@2.8.0/" } } diff --git a/functions/send_time_off_request_to_manager/blocks.ts b/functions/send_time_off_request_to_manager/blocks.ts index 2b34dc5..2ed9fec 100644 --- a/functions/send_time_off_request_to_manager/blocks.ts +++ b/functions/send_time_off_request_to_manager/blocks.ts @@ -9,7 +9,7 @@ export default function timeOffRequestHeaderBlocks(inputs: any): any[] { type: "header", text: { type: "plain_text", - text: `A new time-off request has been submitted`, + text: "A new time-off request has been submitted", }, }, { diff --git a/functions/send_time_off_request_to_manager/blocks_test.ts b/functions/send_time_off_request_to_manager/blocks_test.ts index e556f1a..26adbe0 100644 --- a/functions/send_time_off_request_to_manager/blocks_test.ts +++ b/functions/send_time_off_request_to_manager/blocks_test.ts @@ -1,7 +1,7 @@ -import { assertEquals } from "https://deno.land/std@0.153.0/testing/asserts.ts"; +import { assertEquals } from "@std/assert"; import timeOffRequestHeaderBlocks from "./blocks.ts"; -Deno.test("timeOffRequestHeaderBlocks generates valid blocks for inputs without reason", async () => { +Deno.test("timeOffRequestHeaderBlocks generates valid blocks for inputs without reason", () => { const expectedBlocks = [ { type: "header", @@ -17,7 +17,7 @@ Deno.test("timeOffRequestHeaderBlocks generates valid blocks for inputs without }, { type: "section", text: { type: "mrkdwn", text: "*Reason:* N/A" } }, ]; - const blocks = await timeOffRequestHeaderBlocks({ + const blocks = timeOffRequestHeaderBlocks({ employee: "U12345", start_date: "2022-03-01", end_date: "2022-03-10", @@ -25,7 +25,7 @@ Deno.test("timeOffRequestHeaderBlocks generates valid blocks for inputs without assertEquals(blocks, expectedBlocks); }); -Deno.test("timeOffRequestHeaderBlocks generates valid blocks for full inputs", async () => { +Deno.test("timeOffRequestHeaderBlocks generates valid blocks for full inputs", () => { const expectedBlocks = [ { type: "header", @@ -44,7 +44,7 @@ Deno.test("timeOffRequestHeaderBlocks generates valid blocks for full inputs", a text: { type: "mrkdwn", text: "*Reason:* On vacation!" }, }, ]; - const blocks = await timeOffRequestHeaderBlocks({ + const blocks = timeOffRequestHeaderBlocks({ employee: "U12345", start_date: "2022-03-01", end_date: "2022-03-10", diff --git a/functions/send_time_off_request_to_manager/mod_test.ts b/functions/send_time_off_request_to_manager/mod_test.ts index 6d3dd49..ad0e618 100644 --- a/functions/send_time_off_request_to_manager/mod_test.ts +++ b/functions/send_time_off_request_to_manager/mod_test.ts @@ -1,31 +1,38 @@ -import * as mf from "https://deno.land/x/mock_fetch@0.3.0/mod.ts"; +import { stub } from "@std/testing/mock"; import { SlackFunctionTester } from "deno-slack-sdk/mod.ts"; -import { assertEquals } from "https://deno.land/std@0.153.0/testing/asserts.ts"; +import { assertEquals } from "@std/assert"; import handler from "./mod.ts"; -// Replaces globalThis.fetch with the mocked copy -mf.install(); - -mf.mock("POST@/api/chat.postMessage", async (req) => { - const body = await req.formData(); - if (body.get("channel")?.toString() !== "U22222") { - return new Response(`{"ok": false, "error": "unexpected channel ID"}`, { - status: 200, - }); - } - if (body.get("blocks") === undefined) { - return new Response(`{"ok": false, "error": "blocks are missing!"}`, { - status: 200, - }); - } - return new Response(`{"ok": true, "message": {"ts": "111.222"}}`, { - status: 200, - }); -}); - const { createContext } = SlackFunctionTester("my-function"); Deno.test("SendTimeOffRequestToManagerFunction runs successfully", async () => { + // Replaces globalThis.fetch with the mocked copy + using _fetchStub = stub( + globalThis, + "fetch", + async (url: string | URL | Request, options?: RequestInit) => { + const request = url instanceof Request ? url : new Request(url, options); + + assertEquals(request.method, "POST"); + assertEquals(request.url, "https://slack.com/api/chat.postMessage"); + + const body = await request.formData(); + if (body.get("channel")?.toString() !== "U22222") { + return new Response(`{"ok": false, "error": "unexpected channel ID"}`, { + status: 200, + }); + } + if (body.get("blocks") === undefined) { + return new Response(`{"ok": false, "error": "blocks are missing!"}`, { + status: 200, + }); + } + return new Response(`{"ok": true, "message": {"ts": "111.222"}}`, { + status: 200, + }); + }, + ); + const inputs = { employee: "U11111", manager: "U22222", diff --git a/import_map.json b/import_map.json deleted file mode 100644 index 90f6d26..0000000 --- a/import_map.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "imports": { - "deno-slack-sdk/": "https://deno.land/x/deno_slack_sdk@2.15.0/", - "deno-slack-api/": "https://deno.land/x/deno_slack_api@2.8.0/" - } -} diff --git a/triggers/trigger.ts b/triggers/trigger.ts index 300174a..964b907 100644 --- a/triggers/trigger.ts +++ b/triggers/trigger.ts @@ -1,4 +1,4 @@ -import { Trigger } from "deno-slack-sdk/types.ts"; +import type { Trigger } from "deno-slack-sdk/types.ts"; import { TriggerContextData, TriggerTypes } from "deno-slack-api/mod.ts"; const trigger: Trigger = {